「这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战」。
内存数据的读写
-
从内存中读取数据
使用中括号表示通过地址取值
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 其中 []运算优先
- 向内存中写入数据
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