ARM32汇编语言之内存数据的读写

243 阅读4分钟

「这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战」。

内存数据的读写

  1. 从内存中读取数据

    使用中括号表示通过地址取值

    LDR R0,[R1]               ;将内存地址为R1的字数据读入寄存器R0。
    LDR R0,[R1,R2]       ;将内存地址为R1+R2的字数据读入寄存器R0。
    
    LDR R0,[R1,#8]        ;将内存地址为R1+8的字数据读入寄存器R0。
    LDR R0,[R1,R2]!    ;将内存地址为R1+R2的字数据读入寄存器R0,并将新地 址R1+R2写入R1。
    
    
    
    LDR R0,[R1,#8]!   ;将内存地址为R1+8的字数据读入寄存器R0,并将新地址 R1+8写入R1。
    
    LDR R0,[R1],R2        ;将内存地址为R1的字数据读入寄存器R0,并将新地址 R1+R2写入R1。
    
    
    LDR R0,[R1,R2,LSL#2]!   ;将内存地址为R1+R2×4的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。
    
    
    LDR R0,[R1],R2,LSL#2      ;将内存地址为R1的字数据读入 寄存器R0,并将新地址R1+R2×4写入R1。
    
    
    ;从标号即为地址
       LDR R0,label ;将标号对应的内容赋值给R0
    

复杂格式如LDR R0,[R1],R2,LSL#2 其中 []运算优先

  1. 向内存中写入数据
      STR R0,[R1],#8           ;将R0中的字数据写入以R1为地址的内存中,并 将新地址R1+8写入R1。
       
       
       STR R0,[R1,#8]          ;将R0中的字数据写入以R1+8为地址的内存中。
       
       STRB    R0,[R1]             ;将寄存器R0中的字节数据写入以R1为地 址的内存中。
       STRB    R0,[R1,#8]     ;将寄存器R0中的字节数据写入以R1+8为地址的存 储器中。  
       STR R0,[R1],#8           ;将R0中的字数据写入以R1为地址的内存中,并 将新地址R1+8写入R1。
       
       
       STR R0,[R1,#8]          ;将R0中的字数据写入以R1+8为地址的内存中。
       
       STRB    R0,[R1]             ;将寄存器R0中的字节数据写入以R1为地 址的内存中。
       STRB    R0,[R1,#8]     ;将寄存器R0中的字节数据写入以R1+8为地址的存 储器中。
    

LDR伪指令

这个指令和内存读取指令长的一模一样,如果我们在使用的时候加个等号,那么它就是另外一个指令

;如果不加等号 是内存读取功能
LDR R0,label ;获取标签所对应的内存数据赋给R0  

;一旦加了等号,则变成了传送指令
LDR R0,=label ;将标号对应的实际物理地址值赋值给R0 此时它的作用和mov无异
LDR R0,='a' ;直接将字符数据传送给R0

实际上,加了等号的LDR指令,刚好可以弥补mov指令的不足, mov指令只能传送由八个二进制位右移而得的数据,而LDR则没有这个限制

也就是说如果我们想将一个数值传入寄存器,可以有两种方式:

;第一种
mov R1,#0X100

;第二种
ldr R1,=0x100 

;mov指令的限制:只能传送由八个二进制位右移而得的数据, 也就相当于是两个十六进制数据,由于可以不断移位那么数据的大小可以伸缩,比如以下数据都可使用mov指令
0x00000058  0x00000580 0x00005800  0x00058000 0x00580000 0x05800000 0x58000000 
;我们发现一个规律:mov指令只能传送最大两个十六进制空间的数据,注意是空间,这两个数据随意你移动,一旦不满足这个条件则无法传送,比如
0x00000581

LDR伪指令总结

作用:

  • 弥补mov指令的不足
  • 获取数据所对应的内存地址

ADR指令

那么除了通过LDR伪指令来获取数据所在地址外还有一个指令也可以获取数据地址,那就是adr指令,但这个指令只能获取当前段内数据的地址,段外数据无法获取,ldr则没有这个限制

	AREA test2,CODE
		mov R3,#8
aaaa dcb 1,2,3
		adr R0,aaaa ;获取aaaa首地址
  	END