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

  • 数据搬移指令:
  • 立即数:
  • 在待判断的32位数(以十六进制展开)中,寻找一个0~255(即0x00~0xff)之间的数值,然后将这个数值循环右移偶数个位置,可以得到待判断的数,即为立即数
c 复制代码
	mov //将第二个操作数直接赋值给目标寄存器
    
    mvn //将第二个操作数按位取反,然后再赋值给目标寄存器
  • 示例代码:
c 复制代码
	.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
	
  • 运行结果:
  • ldr伪指令:
  • 示例代码:
c 复制代码
	.text        
	.global _start        
	_start: 
		
		ldr r0, =0x52985298 @数值可以是0~4G(0~2^32)之间的任意数
		
		stop:
			
			b stop
	  
	
	.end
	
	
  • 运行结果:
  • 移位操作指令:
c 复制代码
lsl //逻辑左移或者无符号左移
lsr //逻辑右移或者无符号右移
asr //算数右移或者有符号右移
ror //循环右移
  • 示例代码:
c 复制代码
	.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
	
  • 运行结果:

  • 位运算指令:

  • 记忆技巧:

  • 与0清0,与1不变;

  • 或1置1,或0不变;

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

c 复制代码
	and  //按位与(&)
	orr  //按位或(|)
	eor  //按位异或(^)
	bic  //按位清除的指令
  • 示例代码:
c 复制代码
	.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
	
	
  • 运行结果:

  • 算数运算指令:

c 复制代码
	add //普通加法指令,不需要考虑进位标志位(C位)
	adc //带进位的加法指令,需要考虑进位标志位(C位)
	sub //普通减法指令,不需要考虑借位标志位(C位)
	sbc //带借位的减法指令,需要考虑借位标志位(C位)
	mul //乘法指令
	div //除法指令(ARM-v8之后的架构支持除法指令)
  • 示例代码:
c 复制代码
	.text        
	.global _start        
	_start: 
		/* 案例1:实现两个64位数据的加法运算
	    第1个64位数据,低32位保存到R0中,高32位保存到R1中;
	    第2个64位数据,低32位保存到R2中,高32位保存到R3中;
	    运算结果:低32位保存到R4中,高32位保存到R5中; */
	    
	    @ 1. 准备2个64位数据
	    mov r0, #0xFFFFFFFE  @ 第1个64位数据的低32位
	    mov r1, #0x5   @ 第1个64位数据的高32位
	    mov r2, #0x6   @ 第2个64位数据的低32位
	    mov r3, #0x7   @ 第2个64位数据的高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. 准备2个64位数据
			mov r0, #0x4      @ 第1个64位数据的低32位
			mov r1, #0xF   @ 第1个64位数据的高32位
			mov r2, #0x6   @ 第2个64位数据的低32位
			mov r3, #0x7   @ 第2个64位数据的高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
		
	
  • 运行结果:

  • 比较指令:

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

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

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

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

c 复制代码
	cmp //比较两个数的大小
  • 示例代码:
c 复制代码
	.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
	
	
  • 运行结果:
相关推荐
加油,旭杏16 分钟前
【中间件学习】fastCG介绍和使用
学习·nginx·fastcgi
limengshi13839222 分钟前
通信工程学习:什么是TFTP简单文件传输协议
网络·网络协议·学习·信息与通信
GFCGUO1 小时前
ubuntu18.04运行OpenPCDet出现的问题
linux·python·学习·ubuntu·conda·pip
艾伦~耶格尔2 小时前
Spring Boot 三层架构开发模式入门
java·spring boot·后端·架构·三层架构
丝丝不是土豆丝2 小时前
学习 CSS 新的属性 conic-gradient 实现环形进度条
学习
S hh3 小时前
【Linux】进程地址空间
java·linux·运维·服务器·学习
wusam3 小时前
螺蛳壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习04(环境准备)
学习·docker·centos
攸攸太上3 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
Geek之路4 小时前
QT系统学习篇(1)
开发语言·qt·学习
IFTICing4 小时前
【文献阅读】Attention Bottlenecks for Multimodal Fusion
人工智能·pytorch·python·神经网络·学习·模态融合