• ARM汇编指令之数据操作指令


    • 数据搬移指令:
    • 立即数:
    • 在待判断的32位数(以十六进制展开)中,寻找一个0~255(即0x00~0xff)之间的数值,然后将这个数值循环右移偶数个位置,可以得到待判断的数,即为立即数
    	mov //将第二个操作数直接赋值给目标寄存器
        
        mvn //将第二个操作数按位取反,然后再赋值给目标寄存器
    
    • 1
    • 2
    • 3
    • 示例代码:
    	.text        
    	.global _start        
    	_start: 
    		
    		mov r0, #0x0000ff00 @第二个操作数为立即数,立即数前需要添加“#”
    		mov r1, r0 @实现功能:r1 = r0 = 0x0000ff00
    		
    		mvn r2, #0x0000ff00 @r2 = ~0x0000ff00 = 0xffff00ff
    		
    		mvn r3, r2 @ r3 = ~r2 = 0x0000ff00
    		
    		stop:
    			
    			b stop
    	  
    	
    	.end
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 运行结果:
      在这里插入图片描述
    • ldr伪指令:
    • 示例代码:
    	.text        
    	.global _start        
    	_start: 
    		
    		ldr r0, =0x52985298 @数值可以是0~4G(0~2^32)之间的任意数
    		
    		stop:
    			
    			b stop
    	  
    	
    	.end
    	
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 运行结果:
      在这里插入图片描述
    • 移位操作指令:
    lsl //逻辑左移或者无符号左移
    lsr //逻辑右移或者无符号右移
    asr //算数右移或者有符号右移
    ror //循环右移
    
    • 1
    • 2
    • 3
    • 4
    • 示例代码:
    	.text        
    	.global _start        
    	_start: 
    		
    		/*
    		lsl //逻辑左移或者无符号左移
    		lsr //逻辑右移或者无符号右移
    		asr //算数右移或者有符号右移
    		ror //循环右移
    		*/
    		@逻辑左移:高位移位,低位补0
    		ldr r0, =0x000000ff
    		
    		lsl r1,r0, #4 @ r1 = r0 << 4 = 0x00000ff0
    		
    		@逻辑右移:低位移出,高位补0
    		
    		lsr r2,r0, #4 @ r2 = r0 >> 4 = 0x0000000f
    		
    		@算数右移:低位移出,高位补符号位
    		mov r3,#-0xff @ r3 = 0xffffff01
    		asr r4,r3, #4 @ r4 = 0xfffffff0
    		
    		@循环右移:低位移出,补到高位
    		ror r5,r0, #8 @ r5 = 0xff000000
    		stop:
    			
    			b stop
    	  
    	
    	.end
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 运行结果:
      在这里插入图片描述

    • 位运算指令:

    • 记忆技巧:

    • 与0清0,与1不变;

    • 或1置1,或0不变;

    • 异或1取反,异或0不变;

    	and  //按位与(&)
    	orr  //按位或(|)
    	eor  //按位异或(^)
    	bic  //按位清除的指令
    
    • 1
    • 2
    • 3
    • 4
    • 示例代码:
    	.text        
    	.global _start        
    	_start: 
    		
    		ldr r0, = 0x12345678
    		@将r0寄存器的第7位置1
    		orr r0,r0,#(0x1 << 7)
    		@orr r0,r0, #(1 << 7)
    		@orr r0,r0, #0x80
    		@将r0寄存器的第27位清零,并保证其他位不变,新的操作数移到r1
    		and r0,r0,#(~(0x1 << 27))
    		mov r1,r0
    		@将r0寄存器的第20位到第25位置1,并保证其他位不变,新的操作数移到r2
    		
    		orr r0,r0,#(0x3f << 20)
    		mov r2,r0
    		
    		@将r0寄存器的第12位到第18位清0,并保证其他位不变,新的操作数移到r3
    		and r0,r0, #(~(0x7f << 12))
    		mov r3,r0
    		
    		@将r0寄存器的第11位到第4位修改为0b01101101,并保证其他位不变,新的操作数移到r4
    		and r0,r0, #(~(0xff << 4))
    		orr r0,r0, #(0x6d << 4)
    		mov r4,r0
    		
    		@若第一个寄存器和目标寄存器的编号相同时,可以合并,只写一个寄存器即可
    		orr r0, #(0x1 << 7) @ r0 |= (0x1 << 7)
    		mov r5,r0
    		
    		@将r0寄存器的第7位清0
    		bic r0, #(0x1 << 7)
    		mov r6,r0
    		
    		
    		stop:
    			
    			b stop
    	  
    	
    	.end
    	
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 运行结果:
      在这里插入图片描述

    • 算数运算指令:

    	add //普通加法指令,不需要考虑进位标志位(C位)
    	adc //带进位的加法指令,需要考虑进位标志位(C位)
    	sub //普通减法指令,不需要考虑借位标志位(C位)
    	sbc //带借位的减法指令,需要考虑借位标志位(C位)
    	mul //乘法指令
    	div //除法指令(ARM-v8之后的架构支持除法指令)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 示例代码:
    	.text        
    	.global _start        
    	_start: 
    		/* 案例1:实现两个64位数据的加法运算
    	    第1个64位数据,低32位保存到R0中,高32位保存到R1中;
    	    第2个64位数据,低32位保存到R2中,高32位保存到R3中;
    	    运算结果:低32位保存到R4中,高32位保存到R5中; */
    	    
    	    @ 1. 准备264位数据
    	    mov r0, #0xFFFFFFFE  @ 第164位数据的低32位
    	    mov r1, #0x5   @ 第164位数据的高32位
    	    mov r2, #0x6   @ 第264位数据的低32位
    	    mov r3, #0x7   @ 第264位数据的高32位
    	    
    		 @ 低32位的加法运算
    		 adds r4, r0, r2   @ r4 = r0 + r2 = 0x0000_0004
    		 
    		 @ 高32位的加法运算  @ r5 = r1 + r3 + C = 0x0000_000D
    		 adc r5, r1, r3
    			
    		 /* 案例1:实现两个64位数据的减法运算
    			第1个64位数据,低32位保存到R0中,高32位保存到R1中;
    			第2个64位数据,低32位保存到R2中,高32位保存到R3中;
    			运算结果:低32位保存到R4中,高32位保存到R5中; */
    		 @ 1. 准备264位数据
    			mov r0, #0x4      @ 第164位数据的低32位
    			mov r1, #0xF   @ 第164位数据的高32位
    			mov r2, #0x6   @ 第264位数据的低32位
    			mov r3, #0x7   @ 第264位数据的高32位
    		 
    		 @ 低32位减法运算
    		 subs r4, r0, r2        @ r4 = r0 - r2 = 0xFFFF_FFFE
    		 sbc  r5, r1, r3        @ r5 = r1 - r3 - !C = 0x0000_0007
    		 
    		 @ 案例3:乘法指令
    		 mov r0, #3
    		 mov r1, #4
    		 mul r2, r0, r1    @ r2 = r0 * r1 = 0xC
    		 
    		 @ 乘法指令的第二个操作数只能是一个寄存器
    		 @ mul r3, r0, #5  @ Error
    		
    		stop:
    			
    			b stop
    	  
    	
    	.end
    		
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 运行结果:
      在这里插入图片描述

    • 比较指令:

    • 功能:比较两个数的大小 ;

    • 本质:比较指令的本质做减法运算;

    • 比较指令没有目标寄存器,指令的执行结果影响的是CPSR的NZCV位,并且不需要加S;

    • 比较指令经常和条件码配合使用,实现汇编指令的有条件执行;

    	cmp //比较两个数的大小
    
    • 1
    • 示例代码:
    	.text        
    	.global _start        
    	_start: 
    		
    		mov r0, #16
    		mov r1, #19
    		mov r2, #16
    		mov r3, #19
    		
    		cmp r1,r0
    		
    		subhi r1,r1,r0  @无符号大于
    		
    		cmp r2,r3
    		subcc r3,r3,r2	@无符号小于
    		
    		
    		stop:
    			
    			b stop
    	  
    	
    	.end
    	
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 运行结果:
      在这里插入图片描述
  • 相关阅读:
    强化学习从基础到进阶--案例与实践[7]:深度确定性策略梯度DDPG算法、双延迟深度确定性策略梯度TD3算法详解
    电商API接口领域,有价值数据
    MySQL 与 Redis 缓存的同步方案
    visual stduio code 配置高效舒适web生产环境
    为您的视频编辑应用添加动力,美摄视频剪辑SDK
    解锁前端Vue3宝藏级资料 第五章 Vue 组件应用 1( Props )
    阿里巴巴springcloud的gateway网关如何用继承接口WebExceptionHandler定义一个json格式的404错误页面实例
    鸿蒙智联开发者平台项目的理解介绍
    Java:选择哪个Java IDE好?
    Python与Scrapy:构建强大的网络爬虫
  • 原文地址:https://blog.csdn.net/qq_41878292/article/details/134089913