ARM模式和Thumb模式之间的切换,需要修 改Thumb标志位:
在ARM模式下可以使用BX(Branch and Exchange)指令和BLX(Branch, Link and Exchange)指令来将Thumb标识位置1,从而从 ARM模式切换到Thumb模式。
BX指令和BLX的指令的区别在于,BX除了切换状 态之后,只完成了一个指令跳转的功能(相当于 JMP指令,直接跳转),而BLX指令更像是x86架 构下的CALL指令(会有保存返回地址和重要寄存器 等操作。
ARM指令结构
ARM汇编指令的语法格式
{condition}决定该条指令只有在满足条件时,才会被 执行(主要用在比较指令),该字段依赖于CPSR状态 寄存器的状态。
Operand2,又叫弹性操作数,可以使用的类型包括立 即数、寄存器及带有位运算的寄存器。
指令示例

ARM寻址类型
立即寻址
立即寻址指代指令中包含的立即数,通常用户给寄存器赋初值。
寄存器寻址
寄存器寻址表示操作数来源于寄存器中
寄存器移位寻址
寄存器移位寻址(即桶位移)是ARM指令集中特有的寻址方式
寄存器移位寻址与寄存器寻址类似,只是在进行实际指令操作前,需 要对寄存器中存储的操作数进行移位操作。
寄存器移位寻址
指令的功能是将R1寄存器左移3位,即“R1<<3”后的值赋给 R0寄存器
寄存器间接寻址
寄存器间接寻址中实际操作数来自于寄存器中保存的指针指向 的内存
如果R1存储的地址为0x12345678, 而内存0x12345678中 存储的值为0xdeadbeaf,那么指令执行结束后R0的值为 0xdeadbeaf
基址寻址
基址寻址是将地址码给出的基址寄存器与偏移量相 加,形成最终的内存访问地址
基址寄存器常用于查表、数组访问等操作。
表示从内存R1-4作为内存访问地址(#表示后面的 是一个立即数),从内存中取出值放到R0寄存器中
多寄存器寻址
多寄存器寻址可以在一条指令中实现从内存中加载 多个值到寄存器中,寄存器的数量最多为16个。
LDM是数据加载指令,指令后缀IA表示每完成一个 寄存器的加载,R0的值自增一个字,在32位ARM 处理器中,一个字占的空间是4个字节。在这条指令 执行结束后,R1=[R0], R2=[R0+4], R3=[R0+8], R5=[R0+12]
堆栈寻址
堆栈寻址用于从栈上存取数据
常用的堆栈操作指令有LDMFA/STMFA、 LDMEA/STMEA、LDMFD/STMFD、LDMED/STMED。
LDM和STM为指令前缀
LDM:(load much)多数据加载,将栈地址上的值加载到寄存器上
STM:(store much)多数据存储,将寄存器的值存到栈地址上
STMFD SP!, {R1-R7, LR}
表示将R1~R7,LR这8个寄存器压入栈
后缀
ARM寻址类型
块拷贝寻址
块拷贝寻址用于连续从存储器的某一位置拷贝数据到另一 位置,这种方式本质上和多寄存器寻址是类似的。
表示从R0指向的存储单元中连续读取3个字(对应 3个寄存器),存储到R1-R3寄存器中。
相对寻址
相对寻址以程序计数器PC的当前值作为基地址,指令中的地 址标号作为偏移量,将两者相加之后得到操作数的有效地址
对于BL指令,与指令“MOV R0,R1”之间的偏移量就是指令 偏移量,BL指令执行结束后,PC会更新为指令“MOV R0,R1” 的地址
例如BL FUNC1和MOV R0, R1的距离为0x10,则编译后BL FUNC1为BL 0x10
ARM常用指令介绍
MOV指令
它的功能是将立即数或者寄存器的值拷贝到目标寄 存器。
MVN是数据非传送指令
它的功能是将立即数或者寄存器值按位取反后拷贝 到目标寄存器中。
ADD指令
SUB是减法指令
它的功能是用Rn寄存器减去operand2的值,结果 拷贝到Rd寄存器中。
MUL是32位乘法指令
它的功能是将Rm寄存器与Rn寄存器的值相乘,结 果的低32位保存到Rd寄存器
STM是数据存储指令
用于将寄存器列表的值 保存到指定的存储单元中。
PUSH是堆栈操作指令。
它的格式如下: PUSH{condition}reglist
PUSH指令示例如下:
PUSH {R0,R4-R7} @将R0,R4-R7这五个寄 存器压入到堆栈
POP是堆栈操作指令
指令功能是从堆栈中弹出数据到寄存器列表。它的 格式如下:
POP指令示例如下:
POP {R0,R4-R7} @从堆栈上弹出数据到R0, R4-R7这五个寄存器
B是跳转指令
B指令是最简单的跳转指令,指令跳转使用当前PC 加上指令后面的偏移量来计算出新的PC地址。
BL是链接的跳转指令
当执行BL指令时,如果条件满足,会首先将当前指 令的下一条指令的地址拷贝到R14(也称LR)寄存 器中,然后跳转到label处的指令继续执行。当函数 执行完毕后,子函数通过“MOV PC,LR”回到主 函数。
BX是带状态切换的跳转指令
当执行BX指令时,如果条件满足,处理器会判断 Rm的最低位是否为1,如果为1则在跳转的同时将 CPSR寄存器的标志T置位,并将目标地址处的代码 解释为Thumb指令;反之将CPSR寄存器的标志T 恢复,并将目标代码处的指令解释为ARM指令。
BLX是带链接和状态切换的跳转指令
本质上这条指令结合了BL和BX的功能,当条件满 足的时候,除了设置链接寄存器之外,还会根据 Rm最低位的状态还修改处理器的状态。
SWI/SVC是软中断指令
该指令用于产生软中断,从而实现从用户模式到管 理模式的切换,如系统功能调用。指令格式如下:
在Android系统中,系统功能调用为0号中断,使用R7寄 存器存放系统调用号。使用R0-R3寄存器来保存系统调用 的前4个参数,对于大于4个参数的系统调用,剩余参数采 用堆栈传递。
ARM调试环境
可以选择使用ARM开发板、树莓派或者 Android设备来调试分析ARM汇编指令
除了使用ARM硬件来进行调试分析,也可以使 用QEMU来搭建ARM调试环境。