你的位置:首页 > 操作系统

[操作系统]入门 ARM 汇编(二)—— 寻址方式


忧愁他整天拉着我的心,像一个琴师操练他的琴;悲哀像是海礁间的飞涛:看他那汹涌,听他那呼号!—— 徐志摩·四行诗一首

ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287

立即数寻址

源操作数为立即数,多用于给寄存器赋初值。

 

指令执行后,R1 寄存器的值就是 2。

立即数也可为:十六进制,# 后跟 0x;八进制,# 后跟 0;二进制,# 后跟 0b。

立即数有合法性限制,具体可 google 相关资料。

寄存器寻址

操作数的值在寄存器中。

 

指令执行后,R0 = R5。

速度仅次于立即数寻址。

寄存器移位寻址

类似于寄存器寻址,只是在操作前先对源寄存器操作数进行移位操作。

  •   LSL:逻辑左移,低位补 0
  •   LSR:逻辑右移,高位补 0
  •   ASR:算术右移,移位过程中保持符号位不变(如果源操作数为正数,高位补 0,否则补 1)
  •   ROR:循环右移,移出的低位填入空出的高位
  •   RRX:带扩展的循环右移,高位用进位标志位 C 填充(标志位 C 在 CPSR 中)

 

指令执行后,R1 = R8 * 8。

.W 表示生成 32 位指令。

寄存器间接寻址

由寄存器值指出操作数在内存中的地址。

 

将 R4 寄存器值作为地址,取出此地址中的值赋给 R6。

基址寻址

与寄存器间接寻址有些类似,多用于查表、数组访问等操作。

 

将 R1 寄存器值加 1 作为地址,取出此地址中的值赋给 R0。

LDR 后面加 B,表示是从内存加载字节数据到寄存器。

多寄存器寻址

 

LDM 是数据加载指令,后缀 IA 表示每执行完一次加载操作后 R6 寄存器的值自增 1 个字。

指令执行后,R0 = [R6],R1 = [R6 + #4],R2 = [R6 + #8],R3 = [R6 + #12]。

ARM 指令集中,一个“字”表示一个 32 位的数值。

多寄存器寻址的一条指令最多可以完成 16 个通用寄存器值的传送。

R6 后面的叹号,表示指令执行后,更新基址寄存器 R6 的值。否则,指令执行后 R6 的值是不变的。

堆栈寻址

LDM 和 STM 作为指令前缀,表示多寄存器寻址。

FA、EA、FD、ED 作为指令后缀(指明堆栈生长方向和堆栈指针指向位置等,后面会继续学习)。

 

将数据出栈,保存到 R0、LR,多用于恢复子程序现场。

块拷贝寻址

LDM 和 STM 作为指令前缀,表示多寄存器寻址。

IA、DA、IB、DB 作为指令后缀(指明基址寄存器的递增或递减方式,后面会继续学习)。

示例同“多寄存器寻址”。

相对寻址

将程序计数器 PC 的当前值作为基地址,加上偏移量后得到操作数的有效地址。

 

这里的 BL 采用的就是相对寻址,标号 __libc_format_log 就是偏移量。

学习资料: 《Android 软件安全与逆向分析》