ARM处理器的寻址方式
-立即寻址
-寄存器直接寻址
-寄存器简介寻址
-寄存器移位寻址
-基址寻址
-相对寻址
-多寄存器寻址
-堆栈寻址
1.立即寻址
操作数本身就在指令中直接加以设定,只要取出指令也就取得操作数
第二个来源操作数即为里立即数值,并要求以“#”为前缀.
举例:-ADD R0,R0,#1 ;R0<-R0+1
R0:0x00000000 -------------> R0:0x00000001
ADD R1,R2,#0x3f ;R1<-R2+0x3f
R1:0x00000010 R1:0x0000005f
------------>
R2:0x00000020 R2:0x00000020
2.寄存器直接寻址
利用寄存器中的数值作为操作数
举例:-ADD R0,R1,R2 ;R0<-R1+R2
R0:0x00000001 R0:0x0000007f
R1:0x0000005f ------------------> R1:0x0000005f
R2:0x00000020 R2:0x00000020
3.寄存器间接寻址
以寄存器中的数值作为操作数的地址,而操作数本身是存放在内存中
举例:-LDR R0,[R0] ;R0<-[R1]
R0:0x00000010 R0:0x00000014
--------------->
R1:0x41000000 R1:0x41000000
memory:
0x41000000:0x00000014
0x41000004: ---------
-STR R0,[R1] ;[R1]<-R0
R0:0x00000010
R1:0x41000000
memory
0x41000000:0x00000010
0x41000004: ---------
4.寄存器移位寻址
移位(二进制中)的指令
举例:-ADD R0,R1,R2 LSL#3 ; R0<-R1+R2*8
R0:0x00000001 R0:0x0000015f
R1:0x0000005f --------> R1:0x0000005f
R2:0x00000020 R2:0x00000020
R2 LSL#3 ;R2*8R2的二进制为:0x.....0000 0010 0000 逻辑左移----->0x..........0001 0000 0000即十六进制的0x000001050
5.基址寻址
用于存取基地址附近的内存
-LDR R0,[R1,#8] ;R0<-[R1+8]
(将内存地址为R1+8的数据从内存中取出存入寄存器R0中)
-LDR R0,[R1+R2] ;R0<-[R1+R2]
(将内存地址为R1+R2的数据从内存中取出来存入到寄存器R0中)
-LDR R0,[R1],#8 ;R0<-[R1]
;R1<-R1+8
(将内存地址为R1的数据从内存中取出,存入R0,再将R1改为R1+8)
"!"表示指令在完成资料传送后,同时更新基址寄存器
-LDR R0,[R1,#8]! ;R0<-[R1+8]
;R1<-R1+8
(将内存地址为R1+8的数据从内存中取出来存入R0,在资料传送完毕时,将R1地址更新为R1+8)6.相对寻址:
把pc指针作为基地址,计算出偏移量(偏移量:目的地址和现行指令地址之间的差),基地址加偏移量即得到最终的有效地址
-跳跃指令BL采用了相对寻址的方式
-BL SUBR ;跳转到SUBR
SUBR ......... ;子程序入口
MOV PC,R14 ;返回
(利用链接寄存器(lr):当使用BL或者BLX跳转到子程序的时候,R14保存了返回地址,可以在调用过程结尾恢复;【即在结束使用子程序后,返回主程序中继续进行下一步】 异常终端发生时,这个异常模式特定的物理R14被设置成该异常模式将要返回的地址)
7.多寄存器寻址
一次传递多个寄存器中的值,一条指令中最多传送16个(因为R0-R15)
-LDMIA R0,{R1,R2,R3} ;[R0] ->R1
;[R0+4] ->R2
;[R0+8] ->R3
(将内存中的连续区域的数据传送给多个寄存器)