ARM 体系结构系列——Load/Store指令

1. 字 加载存储指令

● [<Rn>, #+/-<offset_12>]

		MOV		R1, #0x100
		MOV		R0, #0x8	 
		STR		R0, [R1] 	 ;address 0x100 {0x00 00 00 08} 
		STR		R0, [R1, #4] ;address 0x104 {0x00 00 00 08} 
		
		MOV		R1, #0x100
		LDR		R2, [R1]     ; 将内存单元R1中的字读取到R2寄存器中   R2 {0x00 00 00 08}
		LDR		R3, [R1, #4] ; 将内存单元R1+4中的字读取到R3寄存器中 R3 {0x00 00 00 08}

● [<Rn>, +/-]

		MOV		R1, #0x100
		MOV		R0, #0x8	 
		STR		R0, [R1] 	 ;address 0x100 {0x00 00 00 08} 
		STR		R0, [R1, #4] ;address 0x104 {0x00 00 00 08} 

		MOV R2, #0
		MOV R1, #0x104
		LDR R3, [R1, R2]  	; 将内存单元R1+R2(0x104)中的字读取到R3寄存器中 R3 {0x00 00 00 08}
		LDR R4, [R1, -R2] 	; 将内存单元R1-R2(0x100)中的字读取到R4寄存器中 R4 {0x00 00 00 08}

● [<Rn>, +/-,#<shift_imm>]

		MOV		R1, #0x100
		MOV		R2, #1
		MOV		R0, #0x8	 
		STR		R0, [R1, #4] ;address 0x104 {0x00 00 00 08} 
		LDR 	R0, [R1, R2 , LSL #2] ; 将地址单元(R1+R2*4(0x104)中的数据读取到R0{0x08}
		
		MOV		R2, #0x08
		LDR 	R3, [R1, R2 , LSR #1] ; 将地址单元(R1+R2/2(0x104)中的数据读取到R3{0x08}
		LDR 	R4, [R1, R2 , ASR #1] ; 将地址单元(R1+R2/2(0x104)中的数据读取到R4{0x08}
		LDR 	R5, [R1, R2 , ROR #1] ; 将地址单元(R1+R2/2(0x104)中的数据读取到R5{0x08}
		LDR 	R6, [R1, R2 , RRX]    ; 将地址单元(R1+R2/2(0x104)中的数据读取到R6{0x08}	

● [<Rn>, #+/-<offset_12>]!

		MOV		R1, #0x100
		LDR 	R2, [R1, #4]!  ; 将内存单元(R1+4)中数据读取到R0中,同时R1=R1+4{0x104}
		LDR		R3, [R1, #-4]! ; 将内存单元(R1-4)中数据读取到R0中,同时R1=R1-4{0x100}

● [<Rn>, +/-]!

		MOV 	R2, #0x04
		MOV		R1, #0x100
		LDR R0, [R1, R2]! ; 将内存单元(R1+R2)中的数据读取到R0中,同时R1=R1+R2{0x104}
		LDR R0, [R1, -R2]! ; 将内存单元(R1+R2)中的数据读取到R0中,同时R1=R1-R2{0x100}

● [<Rn>, +/-, #<shift_imm>]!

		MOV 	R2, #0x04
		MOV		R1, #0x100
		LDR 	R0, [R1, R2, LSL #2]! ; 将内存单元(R1+R2*4)中的数据读取到R0中,
		; 同时R1=R1+R2*4{0x100 + 0x10 = 0x110}
		
		;{shift ...  LSR,ASR,ROR, RRX}

● [<Rn>], #+/-<offset_12>

		MOV		R1, #0x100
		LDR R0, [R1], #4  ; 将地址为R1{0x100}的内存单元数据读取到R0中,然后R1=R1+4{0x104}
		LDR R0, [R1], #-4 ; 将地址为R1{0x104}的内存单元数据读取到R0中,然后R1=R1-4{0x100}

● [<Rn>], +/-

		MOV		R1, #0x100
		MOV		R2, #0x4
		LDR 	R0, [R1], R2  ; 将地址为R1(0x100)的内存单元数据读取到R0中,然后R1=R1+R2{x0104}
		LDR 	R0, [R1], -R2 ; 将地址为R1(0x104)的内存单元数据读取到R0中,然后R1=R1-R2{0x100}

● [<Rn>], +/-,#<shift_imm>

		MOV		R2, #0x40
		
		LDR 	R0, [R1], R2, LSL #2 ; 将地址为R1(0x100)的内存单元数据读取到R0中,然后R1=R1+R2*4(0x200)
		LDR 	R0, [R1], R2, LSR #2 ; 将地址为R1(0x200)的内存单元数据读取到R0中,然后R1=R1+R2/4 (0x210)
		LDR 	R0, [R1], R2, ASR #2 ; 将地址为R1(0x210)的内存单元数据读取到R0中,然后R1=R1+R2/4 (0x220)
		LDR 	R0, [R1], R2, ROR #2 ; 将地址为R1(0x220)的内存单元数据读取到R0中,然后R1=R1+R2/4 (0x230)
		LDR 	R0, [R1], R2, RRX    ; 将地址为R1的内存单元数据读取到R0中,然后R1=R1+R2/2		 (0x250)

2. 字节/半字 加载存储指令

2.1 原码 补码

  • 计算机指令参与运算的是补码
    源码 = 补码 按位取反 + 1

    MOV R0, #-9 ;R0 {0b11111111111111111111111111110111}
    MOV R1, #9  ;R1 {0b00000000000000000000000000001001}
    

2.2 字节/半字 存储加载

● [<Rn>, #+/-<offset_8>]

		MOV		R1, #0x100
		MOV		R0, #-9	 
		STR		R0, [R1] 	 ;address 0x100 {0xff ff ff f7} or {0b11111111111111111111111111110111}
		
		MOV 	R0, #0
		LDRSB   R0, [R1]  ; 将内存单元R1中的有符号字节数据读取到R0{0b11111111111111111111111111110111}
		; R0中高24位设置成该字节数据的符号位
		
		LDRSB 	R0, [R1, #1] ; 将内存单元(R1+1)中的有符号字节数据读取到R0{0xffffffff = -1}
		; R0中高24位设置成该字节数据的符号位

● [<Rn>, #+/-<offset_8>]!

		MOV		R1, #0x100
		MOV		R0, #-9	 
		STR		R0, [R1] 	 	//address 0x100 {0xff ff ff f7}
		
		LDRSH 	R7, [R1, #0]!  	//将内存单元(R1+0)中的半字数据读取到R7中{0xff ff ff f7},R7中高16位设置成
								//该半字的符号位; R1=R1 + 0
		LDRSH 	R7, [R1, #2]!   //将内存单元(R1+2)中的字节数据读取到R7中{0xffffffff},R7中高16位设置成
								//该半字的符号位; R1=R1+2

● [<Rn>, +/-<Rm>]!

		MOV		R1, #0x100
		MOV		R0, #-9	
		MOV		R2, #2
		STR		R0, [R1] 	 	//address 0x100 {0xff ff ff f7}
		
		LDRH R0, [R1, R2]!      //将内存单元(R1+R2)中的半字数据读取到R0中{0x0000ffff},R0中高16位
							    //设置成0; R1=R1+R2(0x102)
		LDRH R0, [R1, -R2]!     //将内存单元(R1-R2)中的半字数据读取到R0中{0x0000fff7},R0中高16位
								//设置成0; R1=R1-R2 (0x100)

● [<Rn>, +/-<Rm>]

		MOV		R1, #0x100
		MOV		R0, #-9	
		
		MOV		R2, #2
		STRH 	R0, [R1, R2]!  // 将R0中的低16位数据保存到内存单元(R1+R2){0x102}中{fff70000}
		STRH 	R0, [R1, -R2] // 将R0中的低16位数据保存到内存单元(R1-R2){0x100}中{fff7fff7}

● [<Rn>], #+/-<offset_8>

		MOV		R1, #0x100
		MOV		R0, #-9	
		
		STRH 	R0, [R1], #8   		//将R0中的低16位数据保存到内存单元(R1){0x100}中,同时,指令执行后
									//R1=R1+8{0x108}
		STRH 	R0, [R1], #-8 	    //将R0中的低16位数据保存到内存单元(R1)	{0x108}中,同时,指令执行后
									//R1=R1-8{0x100}

● [<Rn>], +/-<Rm>

		STRH R0, [R1], R2  	//将R0中的低16位数据保存到内存单元(R1)中,同时,
							//指令执行后R1=R1+R2
		STRH R0, [R1], -R2 	//将R0中的低16位数据保存到内存单元(R1)中,同时,
							//指令执行后R1=R1-R2

3. 连续字加载/存储指令

● IA (Increment After):事后递增方式。

		MOV		R13, #0x100
		MOV		R1,  #0x100

		MOV		R5, #1
		MOV		R6, #2
		MOV		R7, #3
		MOV		R8,	#4
		
		STMIA 	R1,{R5-R8}		// address 0x100{0x00000001,0x00000002,0x00000003,0x00000004}
		LDMIA 	R1,{R2-R5} 		//将内存单元(0x100)到(0x100 + 12)四个字数据读取到R2~R5的寄存器中

● IB (Increment Before):事先递增方式。

		MOV		R13, #0x100
		MOV		R1, #0x100

		MOV		R5, #1
		MOV		R6, #2
		MOV		R7, #3
		MOV		R8,	#4
		
		STMIB 	R1,{R5-R8}		// address 0x104{0x00000001,0x00000002,0x00000003,0x00000004}
		LDMIB 	R1,{R2-R5} 		//将内存单元(0x104)到(0x104 + 12)四个字数据读取到R2~R5的寄存器中

● DA (Decrement After):事后递减方式。

		MOV		R13, #0x10000
		MOV		R1, #0x1000
		
		MOV		R5, #1
		MOV		R6, #2
		MOV		R7, #3
		MOV		R8,	#4
		
		STMDA 	R1,{R5-R8}		// address 0x1000-0x12 {0x00000001,0x00000002,0x00000003,0x00000004}
		LDMDA 	R1,{R2-R5} 		// address 0x1000-0x12 ,四个字数据读取到R2~R5的寄存器中

● DB (Decrement Before):事先递减方式。

		MOV		R13, #0x10000
		MOV		R1, #0x1000
		
		MOV		R5, #1
		MOV		R6, #2
		MOV		R7, #3
		MOV		R8,	#4
		STMDB 	R1,{R5-R8}		// address 0x1000-0x16 {0x00000001,0x00000002,0x00000003,0x00000004}
		LDMDB 	R1,{R2-R5} 		// address 0x1000-0x16 ,四个字数据读取到R2~R5的寄存器中
		
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值