x86处理器支持7种寻址方式,arm处理器支持9种寻址方式
1. 立即寻址
立即寻址指令中后面的地址码部分为立即数(常量或常数),多用于给寄存器赋初值
MOV R0, #1234 @@指令执行后R0=1234,表十六进制数值以0x开头,如#0x20
2. 寄存器寻址
寄存器寻址,操作数的值在寄存器中,指令执行从寄存器取值操作
MOV R0, R1 @指令执行后,R0=R1
3. 寄存器移位寻址
在操作前需要对源寄存器操作数进行移位操作, 支持五种移位操作:
LSL: 逻辑左移,移位后寄存器空出的低位补0;
LSR: 逻辑右移,移位后寄存器空出的高位补0;
ASR: 算术右移,移位过程中符号位保持不变,如果源操作数为正数,则移位后空出的高位补0,否则补1.
ROR: 循环右移,移位后移出的低位填入移位空出的高位
RRX: 带扩展的循环右移,操作数右移一位,移位空出的高位用C标志的值填充
MOV R0, R1, LSL #2 @将R1寄存器左移2位,即R1<<2后赋值给R0寄存器
4. 寄存器间接寻址
寄存器间接寻址是操作数的地址指针,所需的操作数保存在寄存器指定地址的存储单元
LDR R0, [R1] @将R1寄存器的数值作为地址,取出此地址中的值赋值给R0寄存器
5. 基址寻址
基址寻址是将基址寄存器与偏移量相加,形成操作数的有效地址。基址寻址多用于查表、数组访问等操作
LDR R0, [R1, #-4] @将R1寄存器的数值减4作为地址,取出此地址的值赋给R0寄存器
6. 多寄存器寻址
多寄存器寻址一条指令最多可以完成16个通用寄存器值的传送
LDMIA R0, {R1, R2, R3, R4}
@LDM是数据加载指令,指令IA表示每次执行完加载操作后R0寄存器的值自增1个字(ARM指令字表示一个32位数@值),R1=[R0], R2=[R0+#4], R3=[R0+#8], R4=[R0+#12]
7. 堆栈寻址
堆栈寻址需要使用特定的指令来完成,指令有个LDMFA/STMFA、LDMEA/STMEA、LDMFD/STMFD、LDMED/STMED. LDM和STM为指令前缀表示多寄存器寻址,一次可以传送多个寄存器值,FA/EA/FD/ED为指令后缀。
mode | 含义 |
FD | 满递减堆栈。堆栈向低地址生长,堆栈指针指向最后一个入栈的有效数据项 |
FA | 满递减堆栈,堆栈向高地址生长,堆栈指针指向下一个要放入的空地址 |
ED | 空递减堆栈。堆栈向低地址生长 |
EA | 空递增堆栈。堆栈向高地址生长 |
STMFD SP!, {R1-R7, LR} @将R1~R7,LR入栈。多用于保存子程序现场
LDMFD SP!, {R1-R7, LR} @将数据出栈,放入R1~R7,放入R1~R7,LR寄存器。多用于恢复子程序现场
8. 块拷贝寻址
快拷贝寻址可实现连续地址数据从存储器的某一位置拷贝到另一位置。指令有个LDMIA/STMIA、LDMDA/STMDA、LDMIB/STMIB、LDMDB/STMDB. LDM和STM为指令前缀表示多寄存器寻址,一次可以传送多个寄存器值,IA/DA/IB/DB为指令后缀
LDMIA R0!, {R1-R3} @从R0寄存器指向的存储单元中读取3个字节到R1-R3寄存器
STMIA R0!, {R1-R3} @存储R1-R3寄存器的内容到R0寄存器指向的存储单元
9 相对寻址
相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。
BL NEXT @跳到NEXT标号处执行
......
NEXT: @标号NEXT就是偏移量
......