01-ARM架构汇编
一、基础概念铺垫
-
RISC:ARM芯片属于精简指令集计算机(RISC:Reduced Instruction Set Computing),它所用的指令比较简单,有如下特点:
① 对内存只有读、写指令
② 对于数据的运算是在CPU内部实现
③ 使用RISC指令的CPU复杂度小一点,易于设计
![image]()
对于上图所示的乘法运算a = a * b,
在RISC中要使用4条汇编指令:
① 读内存a
② 读内存b
③ 计算a*b
④ 把结果写入内存
-
寄存器:在CPU内部,使用寄存器保存下图a、b、a+b值,ARM架构常用 32 位寄存器(R0-R15),其中:
- R0-R7:通用寄存器(函数调用时常用 R0-R3 传递参数)
- R13(SP):栈指针寄存器(指向栈顶)
- R14(LR):链接寄存器(保存函数返回地址)
- R15(PC):程序计数器(指向当前执行指令的下一条)
![image]()
![image]()
xPSR 是一个 32 位寄存器,主要用于保存程序运行中的状态信息,包括运算结果的标志、当前执行状态、中断信息等。它由三个部分组成,可单独访问也可整体访问:
-
APSR(应用程序状态寄存器):保存算术 / 逻辑运算产生的标志位(与条件码直接相关),是 xPSR 中最常用的部分。关键标志位(32 位中的高 4 位,bit31-bit28):
- N(Negative,位 31):负标志。运算结果为负数(最高位为 1)时置 1,否则置 0。
- Z(Zero,位 30):零标志。运算结果为 0 时置 1,否则置 0。
- C(Carry,位 29):进位 / 借位标志。
- 加法时结果产生进位(无符号数溢出)置 1;
- 减法时结果产生借位(无符号数不够减)置 1;
- 移位指令中,最后移出的位会存入 C。
- V(Overflow,位 28):溢出标志。有符号数运算时结果超出表示范围(溢出)置 1,否则置 0。
例如:执行
ADD R0, R1, R2后,APSR 的 N/Z/C/V 会根据 R1+R2 的结果自动更新。 -
IPSR(中断程序状态寄存器):保存当前正在服务的中断号(仅在中断处理时有效),用于标识当前响应的是哪个中断。
-
EPSR(执行程序状态寄存器):保存与指令执行相关的状态,例如:
- Thumb 状态标志(Cortex-M 只支持 Thumb 指令集,此位固定为 1);
- 异常返回地址的相关信息等。
- 条件码:ARM 指令可加条件后缀(如
EQ、NE),根据 CPSR(当前程序状态寄存器)的标志位执行,实现条件判断(类似高级语言的if)。
二、数据处理指令
1. MOV:数据移动(寄存器→寄存器 / 立即数→寄存器)
-
格式:
MOV{条件} 目标寄存器, 源数据 -
功能:将源数据(立即数或寄存器值)复制到目标寄存器
-
示例:
MOV R0, #10 ; R0 = 10(立即数10存入R0,#表示立即数) MOV R1, R0 ; R1 = R0(将R0的值复制到R1) MOVNE R2, #0 ; 若条件为NE(不相等),则R2=0(带条件的移动)
2. ADD/SUB:加法 / 减法
-
格式:
ADD{条件} 目标寄存器, 操作数1, 操作数2(SUB格式相同) -
功能:
目标 = 操作数1 ± 操作数2(操作数可以是寄存器或立即数) -
示例:
ADD R3, R1, R2 ; R3 = R1 + R2 ADD R4, R0, #5 ; R4 = R0 + 5 SUB R5, R3, #2 ; R5 = R3 - 2 SUB R0, R0, #1 ; R0 = R0 - 1
3. CMP:比较(影响标志位,用于条件判断)
-
格式:
CMP 操作数1, 操作数2 -
功能:计算
操作数1 - 操作数2,结果不保存,但会更新 CPSR (程序状态寄存器)的标志位(Z:零标志,N:负标志等),供后续条件指令使用。 -
示例:
CMP R0, R1 ; 比较R0和R1的值 ; 若R0=R1,Z标志置1;若R0>R1,C标志置1;若R0<R1,N标志置1
三、跳转指令(控制程序流程)
1. B:无条件跳转(不保存返回地址)
-
格式:
B{条件} 目标标签 -
功能:直接跳转到
目标标签处执行,不保存当前地址(无法返回)。 -
示例:
B loop ; 无条件跳转到loop标签 BEQ exit ; 若CMP结果为相等(Z=1),则跳转到exit(带条件的跳转)
2. BL:带链接的跳转(保存返回地址,用于函数调用)
-
格式:
BL{条件} 目标标签 -
功能:跳转前将当前 PC(下一条指令地址)存入 LR(R14),再跳转到目标标签,用于函数调用(可通过
BX LR返回)。 -
示例:
BL func ; 调用func函数(返回地址存入LR) ... ; func执行完后,通过BX LR返回这里继续执行
3. BX/BLX:跳转并切换指令集(Thumb/ARM)
-
格式:
BX 寄存器(BLX类似,同时保存返回地址) -
功能:跳转到寄存器指向的地址,若寄存器最低位为 1,切换到 Thumb 指令集;为 0 则保持 ARM 指令集。
BX LR是函数返回的常用方式。 -
示例:
BX LR ; 从函数返回(跳转到LR保存的地址)
四、内存访问指令(ARM 是 “加载 - 存储” 架构,只能通过这些指令访问内存)
1. LDR:从内存加载数据到寄存器
-
格式:
LDR{条件} 目标寄存器, [源寄存器, 偏移量] -
功能:从
源寄存器+偏移量指向的内存地址,读取数据到目标寄存器。 -
示例:
LDR R0, [R1] ; R0 = 内存[R1](R1指向的内存数据加载到R0) LDR R2, [R3, #4] ; R2 = 内存[R3+4](偏移4字节的内存数据加载到R2) LDR R4, [R5, R6] ; R4 = 内存[R5+R6](寄存器偏移)
2. STR:将寄存器数据存储到内存
-
格式:
STR{条件} 源寄存器, [目标寄存器, 偏移量] -
功能:将源寄存器的值,写入
目标寄存器+偏移量指向的内存地址。 -
示例:
STR R0, [R1] ; 内存[R1] = R0(R0的值存入R1指向的内存) STR R2, [SP, #-4]! ; 先SP=SP-4,再内存[SP] = R2(栈操作常用,!表示更新SP)
五、栈操作指令(函数调用时保存 / 恢复寄存器)
1. PUSH:将寄存器压入栈(SP 减小)
-
格式:
PUSH {寄存器列表} -
功能:将列表中的寄存器值依次压入栈(栈是向下生长的,SP 自动减小)。
-
示例:
PUSH {R0, R1, LR} ; 将R0、R1、LR的值压入栈(保存现场)
2. POP:从栈中弹出数据到寄存器(SP 增大)
-
格式:
POP {寄存器列表} -
功能:从栈顶依次弹出数据到列表中的寄存器(SP 自动增大)。
-
示例:
POP {R0, R1, PC} ; 从栈中恢复R0、R1的值,最后将栈顶值存入PC(实现返回)
六、常用条件码(指令后缀)
ARM 指令可加条件后缀,根据 CPSR 标志位决定是否执行,常用如下:
| 条件码 | 含义(标志位) | 对应场景 |
|---|---|---|
EQ |
相等(Z=1) | if (a == b) |
NE |
不相等(Z=0) | if (a != b) |
GT |
大于(N=0 且 Z=0) | if (a > b) |
LT |
小于(N=1) | if (a < b) |
AL |
总是执行(默认,可省略) | 无条件执行 |
示例:
CMP R0, #10 ; 比较R0和10
BEQ equal ; 若相等(Z=1),跳转到equal
BNE not_equal ; 若不相等(Z=0),跳转到not_equal
equal:
MOV R1, #0
not_equal:
MOV R1, #1
七、C函数的反汇编
C函数:
int add(volatile int a, volatile int b)
{
volatile int sum;
sum = a + b;
return sum;
}
让Keil生成反汇编:

为例方便复制,制作反汇编的指令如下:
fromelf --text -a -c --output=xxx.dis xxx.axf
C函数add的反汇编代码如下:
i.add
add
0x08002f34: b503 .. PUSH {r0,r1,lr}
0x08002f36: b081 .. SUB sp,sp,#4
0x08002f38: e9dd0101 .... LDRD r0,r1,[sp,#4]
0x08002f3c: 4408 .D ADD r0,r0,r1
0x08002f3e: 9000 .. STR r0,[sp,#0]
0x08002f40: bd0e .. POP {r1-r3,pc}
- 第一列(地址):指令在单片机内存(通常是 Flash)中的存储地址(如
0x08002f34),CPU 通过这个地址找到要执行的指令(PC 寄存器会指向这个地址)。 - 第二列(机器码):二进制指令的十六进制形式(16 进制比二进制简短,方便显示),例如
b503对应的二进制是10110101 00000011,这串二进制是 CPU 能直接解析的 “命令”。 - 第三列(汇编码):机器码的助记符,用汇编(如
PUSH、ADD)表示指令功能,让开发者能理解这条指令在做什么(比如PUSH {r0,r1,lr}表示 “将 r0、r1、lr 寄存器压入栈”)。




浙公网安备 33010602011771号