ARM处理器支持九种寻址方式,分别是:立即寻址、寄存器寻址、寄存器间接寻址、寄存器移位寻址、基址变址寻址、多寄存器寻址、堆栈寻址、块拷贝寻址、相对寻址
立即寻址
例如:
MOV R0, #1234
作用是将十进制数1234赋值给R0,运行结果是R0 = 1234, 立即数以“#”作为前缀,十六进制数以“0x”开头,如#0x12。
寄存器寻址
例如:
ADD R0, R1, R2
作用是将R1+R2的值赋值给R0寄存器,运行结果R0=R1+R2。
寄存器间接寻址
例如:
LDR R0, [R1]
LDR用于从存储器加载数据到寄存器,该指令作用是将R1寄存器中的数值作为地址,将此地址中的数值赋值给R0寄存器。
寄存器移位寻址
例如:
MOV R0, R1, LSL #2
作用是将R1寄存器左移两位,即“R1<<2”后赋值给R0寄存器,指令执行后R0=R1*4
寄存器移位寻址支持五种位移操作:
- LSL(Logical Shift Left):逻辑左移,移位后寄存器空出的低位补0;
- LSR(Logical Shift Right):逻辑右移,移位后寄存器空出的高位补0;
- ASR(Arithmetic Shift Right):算数右移,移位过程中符号位保持不变,如果源操作数是正数,则移位后空出的高位补0,否则补1;
- ROR(Rotate Right):循环右移,移位后移出的低位填入移位空出的高位;
- RRX(Rotate Right with extend):带扩展的循环右移,操作数右移一位,移位空出的高位用处理器的进位标志(C标志)的值填充。
寄存器基址变址寻址
例如:
LDR R0,[R1,#-4]
作用是将R1寄存器中的值减4作为地址,将该地址中的值赋值给R0。
多寄存器寻址
例如:
LDMIA R0,{R1,R2,R3,R4}
LDM是数据加载指令,指令的后缀IA表示每次执行完加载操作后R0寄存器的值自增1个字,ARM指令集中,字表示的是32位的数值。这条指令执行后,R1=[R0], R2=[R0+#4], R3=[R0+#8], R4=[R0+#12]。
堆栈寻址
例如:
STMFD SP!,{R1-R7, LR} ;将R1-R7, LR压入堆栈。满递减堆栈,多用于保存子程序“现场”。
LDMED SP!,{R1-R7, LR} ;将堆栈中的数据取回到R1-R7, LR寄存器。空递减堆栈,多用于恢复子程序“现场”。
块拷贝寻址
可实现连续地址数据从存储器的某一位置拷贝到另一位置。
例如:
LDMIA R0!, {R1-R3} ;从R0寄存器指向的存储单元中读取3个字到R1-R3寄存器
STMIA R0!, {R1-R3} ;存储R1-R3寄存器的内容到R0寄存器指向的存储单元
相对寻址
以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。
例如:
BL NEXT
……
NEXT:
……
BL NEXT是跳到NEXT标号处执行。这里的BL采用的就是相对寻址,标号NEXT就是偏移量。