一、指令格式说明
| 符号 | 含义 |
|---|
{cond} | 条件后缀(EQ、NE、GT、LT 等),可选 |
{S} | 更新 CPSR 标志位(N、Z、C、V) |
Rd | 目标寄存器 |
Rn | 第一个源寄存器 |
Rm | 第二个源寄存器 |
Rs | 移位值寄存器 |
operand2 | 灵活的第二操作数(立即数、寄存器、移位寄存器) |
label | 代码标签 |
imm | 立即数 |
reglist | 寄存器列表,如 {R0-R3, LR} |
灵活的第二操作数(operand2)
| 格式 | 说明 | 示例 |
|---|
#imm | 立即数 | ADD R0, R1, #0x10 |
Rm | 寄存器 | ADD R0, R1, R2 |
Rm, LSL #n | 逻辑左移 n 位 | ADD R0, R1, R2, LSL #2 |
Rm, LSL Rs | 逻辑左移 Rs 位 | ADD R0, R1, R2, LSL R3 |
Rm, LSR #n | 逻辑右移 n 位 | ADD R0, R1, R2, LSR #4 |
Rm, ASR #n | 算术右移 n 位 | ADD R0, R1, R2, ASR #8 |
Rm, ROR #n | 循环右移 n 位 | ADD R0, R1, R2, ROR #16 |
Rm, RRX | 带进位的循环右移 | ADD R0, R1, R2, RRX |
二、数据处理指令
2.1 数据传送
| 指令 | 格式 | 操作 | 示例 |
|---|
| MOV | MOV{cond}{S} Rd, operand2 | Rd = operand2 | MOV R0, #0x12 |
| MVN | MVN{cond}{S} Rd, operand2 | Rd = ~operand2 | MVN R0, #0x0F |
2.2 算术运算
| 指令 | 格式 | 操作 | 示例 |
|---|
| ADD | ADD{cond}{S} Rd, Rn, operand2 | Rd = Rn + operand2 | ADD R0, R1, #10 |
| ADC | ADC{cond}{S} Rd, Rn, operand2 | Rd = Rn + operand2 + C | ADC R0, R1, R2 |
| SUB | SUB{cond}{S} Rd, Rn, operand2 | Rd = Rn - operand2 | SUB R0, R1, #5 |
| SBC | SBC{cond}{S} Rd, Rn, operand2 | Rd = Rn - operand2 - (1-C) | SBC R0, R1, R2 |
| RSB | RSB{cond}{S} Rd, Rn, operand2 | Rd = operand2 - Rn | RSB R0, R1, #0 |
2.3 逻辑运算
| 指令 | 格式 | 操作 | 示例 |
|---|
| AND | AND{cond}{S} Rd, Rn, operand2 | Rd = Rn & operand2 | AND R0, R1, #0xFF |
| ORR | ORR{cond}{S} Rd, Rn, operand2 | Rd = Rn | operand2 | ORR R0, R1, #0x01 |
| EOR | EOR{cond}{S} Rd, Rn, operand2 | Rd = Rn ^ operand2 | EOR R0, R1, R2 |
| BIC | BIC{cond}{S} Rd, Rn, operand2 | Rd = Rn & ~operand2 | BIC R0, R1, #0x0F |
2.4 比较测试
| 指令 | 格式 | 操作 | 更新标志 | 示例 |
|---|
| CMP | CMP{cond} Rn, operand2 | Rn - operand2 | N、Z、C、V | CMP R0, #10 |
| CMN | CMN{cond} Rn, operand2 | Rn + operand2 | N、Z、C、V | CMN R0, R1 |
| TST | TST{cond} Rn, operand2 | Rn & operand2 | N、Z | TST R0, #0x01 |
| TEQ | TEQ{cond} Rn, operand2 | Rn ^ operand2 | N、Z | TEQ R0, R1 |
2.5 乘法指令
| 指令 | 格式 | 操作 | 示例 |
|---|
| MUL | MUL{cond}{S} Rd, Rm, Rs | Rd = Rm * Rs(低 32 位) | MUL R0, R1, R2 |
| MLA | MLA{cond}{S} Rd, Rm, Rs, Rn | Rd = Rm * Rs + Rn | MLA R0, R1, R2, R3 |
| UMULL | UMULL{cond}{S} RdLo, RdHi, Rm, Rs | (RdHi,RdLo) = Rm * Rs(无符号) | UMULL R0, R1, R2, R3 |
| SMULL | SMULL{cond}{S} RdLo, RdHi, Rm, Rs | (RdHi,RdLo) = Rm * Rs(有符号) | SMULL R0, R1, R2, R3 |
| UMLAL | UMLAL{cond}{S} RdLo, RdHi, Rm, Rs | (RdHi,RdLo) += Rm * Rs | UMLAL R0, R1, R2, R3 |
| SMLAL | SMLAL{cond}{S} RdLo, RdHi, Rm, Rs | (RdHi,RdLo) += Rm * Rs(有符号) | SMLAL R0, R1, R2, R3 |
2.6 移位操作(作为 operand2)
| 操作 | 语法 | 效果 |
|---|
| 逻辑左移 | LSL #n | 左移 n 位,低位补 0 |
| 逻辑右移 | LSR #n | 右移 n 位,高位补 0 |
| 算术右移 | ASR #n | 右移 n 位,高位补符号位 |
| 循环右移 | ROR #n | 循环右移 n 位 |
| 带进位循环右移 | RRX | 通过 C 位循环右移 1 位 |
三、加载/存储指令
3.1 单寄存器传输
| 指令 | 格式 | 操作 | 示例 |
|---|
| LDR | LDR{cond} Rd, [Rn {, #offset}] | Rd = *(Rn + offset) | LDR R0, [R1, #4] |
| LDR | LDR{cond} Rd, [Rn, #offset]! | Rn += offset; Rd = *Rn | LDR R0, [R1, #4]! |
| LDR | LDR{cond} Rd, [Rn], #offset | Rd = *Rn; Rn += offset | LDR R0, [R1], #4 |
| STR | STR{cond} Rd, [Rn {, #offset}] | *(Rn + offset) = Rd | STR R0, [R1] |
| LDRB | LDRB{cond} Rd, [Rn] | Rd = *(unsigned char*)Rn | LDRB R0, [R1] |
| LDRSB | LDRSB{cond} Rd, [Rn] | Rd = *(signed char*)Rn | LDRSB R0, [R1] |
| LDRH | LDRH{cond} Rd, [Rn] | Rd = *(unsigned short*)Rn | LDRH R0, [R1] |
| LDRSH | LDRSH{cond} Rd, [Rn] | Rd = *(signed short*)Rn | LDRSH R0, [R1] |
| STRB | STRB{cond} Rd, [Rn] | *(unsigned char*)Rn = Rd | STRB R0, [R1] |
| STRH | STRH{cond} Rd, [Rn] | *(unsigned short*)Rn = Rd | STRH R0, [R1] |
3.2 多寄存器传输
| 指令 | 格式 | 操作 | 示例 |
|---|
| LDMIA | LDMIA{cond} Rn{!}, reglist | 从 Rn 加载,地址递增 | LDMIA R0!, {R1-R4} |
| LDMDB | LDMDB{cond} Rn{!}, reglist | 从 Rn 加载,地址递减 | LDMDB R0, {R1-R4} |
| STMIA | STMIA{cond} Rn{!}, reglist | 存储到 Rn,地址递增 | STMIA R0!, {R1-R4} |
| STMDB | STMDB{cond} Rn{!}, reglist | 存储到 Rn,地址递减 | STMDB SP!, {R0-R3, LR} |
| PUSH | PUSH{cond} reglist | 压栈(STMDB SP!) | PUSH {R0-R3, LR} |
| POP | POP{cond} reglist | 出栈(LDMIA SP!) | POP {R0-R3, PC} |
3.3 栈操作别名
| 别名 | 真实指令 | 方向 | 说明 |
|---|
PUSH {reglist} | STMDB SP!, {reglist} | 满递减 | 压栈 |
POP {reglist} | LDMIA SP!, {reglist} | 满递减 | 出栈 |
四、分支指令
| 指令 | 格式 | 操作 | 范围 | 示例 |
|---|
| B | B{cond} label | PC = label | ±32MB | B loop |
| BL | BL{cond} label | LR = PC+4; PC = label | ±32MB | BL function |
| BX | BX{cond} Rm | PC = Rm & 0xFFFFFFFE; CPSR.T = Rm & 1 | 任意 | BX LR |
| BLX | BLX Rm | LR = PC+4; PC = Rm & 0xFFFFFFFE; CPSR.T = Rm & 1 | 任意 | BLX func |
五、条件码速查表
| 条件码 | 含义 | 标志条件 | C 语言等价 |
|---|
| EQ | 相等 | Z == 1 | if (a == b) |
| NE | 不等 | Z == 0 | if (a != b) |
| CS/HS | 进位/无符号≥ | C == 1 | if (a >= b) 无符号 |
| CC/LO | 无进位/无符号< | C == 0 | if (a < b) 无符号 |
| MI | 负数 | N == 1 | if (a < 0) |
| PL | 非负数 | N == 0 | if (a >= 0) |
| VS | 溢出 | V == 1 | if (overflow) |
| VC | 无溢出 | V == 0 | if (!overflow) |
| HI | 无符号大于 | C == 1 && Z == 0 | if (a > b) 无符号 |
| LS | 无符号小于等于 | C == 0 | | Z == 1 | if (a <= b) 无符号 |
| GE | 有符号≥ | N == V | if (a >= b) 有符号 |
| LT | 有符号< | N != V | if (a < b) 有符号 |
| GT | 有符号> | Z == 0 && N == V | if (a > b) 有符号 |
| LE | 有符号≤ | Z == 1 | | N != V | if (a <= b) 有符号 |
| AL | 无条件 | 任何 | goto |
六、程序状态寄存器指令
| 指令 | 格式 | 操作 | 示例 |
|---|
| MRS | MRS{cond} Rd, CPSR | Rd = CPSR | MRS R0, CPSR |
| MRS | MRS{cond} Rd, SPSR | Rd = SPSR | MRS R1, SPSR |
| MSR | MSR{cond} CPSR_<fields>, Rn | CPSR_<fields> = Rn | MSR CPSR_c, R0 |
| MSR | MSR{cond} CPSR_<fields>, #imm | CPSR_<fields> = imm | MSR CPSR_f, #0x80000000 |
CPSR 域后缀
| 后缀 | 含义 | 位位置 | 用途 |
|---|
_c | 控制域 | [7:0] | 模式、中断使能 |
_x | 扩展域 | [15:8] | 保留 |
_s | 状态域 | [23:16] | Thumb 状态等 |
_f | 标志域 | [31:24] | N、Z、C、V 标志 |
七、异常与协处理器指令
| 指令 | 格式 | 操作 | 示例 |
|---|
| SVC | SVC{cond} #imm24 | 触发 SVC 异常 | SVC #0x01 |
| BKPT | BKPT #imm16 | 触发断点异常 | BKPT #0 |
| SMC | SMC #imm | 安全监控调用 | SMC #0 |
| HVC | HVC #imm | 虚拟化调用 | HVC #0 |
| MRC | MRC{cond} p15, op1, Rd, CRn, CRm, op2 | CP → ARM | MRC p15, 0, R0, c0, c0, 0 |
| MCR | MCR{cond} p15, op1, Rd, CRn, CRm, op2 | ARM → CP | MCR p15, 0, R0, c12, c0, 0 |
八、伪指令速查表
| 伪指令 | 格式 | 翻译结果 | 示例 |
|---|
| LDR | LDR Rd, =constant | MOV/MVN 或 LDR+文字池 | LDR R0, =0x12345678 |
| LDR | LDR Rd, =label | LDR Rd, [PC, #offset] | LDR R0, =array |
| ADR | ADR Rd, label | ADD Rd, PC, #offset | ADR R0, str |
| ADRL | ADRL Rd, label | 多条 ADD/SUB | ADRL R0, far |
| NOP | NOP | MOV R0, R0 | NOP |
| ALIGN | ALIGN {n} | 插入填充字节 | ALIGN 4 |
| LTORG | LTORG | 强制插入文字池 | LTORG |
九、数据定义伪指令
| 伪指令 | 格式 | 用途 | 示例 |
|---|
| DCB | DCB byte1, byte2, ... | 定义字节常量 | DCB 0x12, 'A', 0x34 |
| DCW | DCW half1, half2, ... | 定义半字常量 | DCW 0x1234, 0x5678 |
| DCD | DCD word1, word2, ... | 定义字常量 | DCD 0x12345678 |
| DCQ | DCQ quad1, quad2, ... | 定义双字常量 | DCQ 0x123456789ABCDEF0 |
| SPACE | SPACE bytes | 预留空间 | SPACE 256 |
| FILL | FILL bytes, unit, value | 填充空间 | FILL 64, 1, 0xFF |
| EQU | name EQU value | 定义符号常量 | GPIO_BASE EQU 0x40020000 |
| ASCIZ | .asciz "string" | 定义字符串(自动加 0) | .asciz "Hello" |
十、CP15 常用寄存器地址
| 寄存器 | CRn | opc1 | CRm | opc2 | 功能 |
|---|
| MIDR | c0 | 0 | c0 | 0 | 处理器 ID |
| MPIDR | c0 | 0 | c0 | 5 | 多核 ID |
| SCTLR | c1 | 0 | c0 | 0 | 系统控制 |
| ACTLR | c1 | 0 | c0 | 1 | 辅助控制 |
| CPACR | c1 | 0 | c0 | 2 | 协处理器访问 |
| TTBR0 | c2 | 0 | c0 | 0 | 页表基址 0 |
| TTBR1 | c2 | 0 | c0 | 1 | 页表基址 1 |
| TTBCR | c2 | 0 | c0 | 2 | 页表控制 |
| DACR | c3 | 0 | c0 | 0 | 域访问控制 |
| DFSR | c5 | 0 | c0 | 0 | 数据异常状态 |
| IFSR | c5 | 0 | c0 | 1 | 指令异常状态 |
| DFAR | c6 | 0 | c0 | 0 | 数据异常地址 |
| VBAR | c12 | 0 | c0 | 0 | 向量表基址 |
| CBAR | c15 | 4 | c0 | 0 | 外设基址 |
十一、内存屏障指令
| 指令 | 功能 | 说明 |
|---|
| DSB | Data Synchronization Barrier | 等待所有内存访问完成 |
| DMB | Data Memory Barrier | 保证内存访问顺序 |
| ISB | Instruction Synchronization Barrier | 冲刷流水线,重新取指 |
十二、处理器模式号
| 模式 | 缩写 | 模式号 |
|---|
| User | USR | 0x10 |
| FIQ | FIQ | 0x11 |
| IRQ | IRQ | 0x12 |
| Supervisor | SVC | 0x13 |
| Monitor | MON | 0x16 |
| Abort | ABT | 0x17 |
| Hyp | HYP | 0x1A |
| Undefined | UND | 0x1B |
| System | SYS | 0x1F |
十三、常用指令组合模板
函数调用与返回
; 函数调用
BL function_name
; 简单函数返回
MOV PC, LR
; 保存 LR 的嵌套函数
PUSH {LR}
BL sub_function
POP {PC}
; 保存多个寄存器的函数
PUSH {R4-R11, LR}
; ... 函数体 ...
POP {R4-R11, PC}
条件判断
; if (a == b)
CMP R0, R1
BEQ equal_label
; if (a > b) 有符号
CMP R0, R1
BGT greater_label
; if (a > b) 无符号
CMP R0, R1
BHI greater_label
循环结构
; for (i = 0; i < n; i++)
MOV R0, #0 ; i = 0
loop:
CMP R0, R1 ; i < n?
BGE loop_end
; ... 循环体 ...
ADD R0, R0, #1 ; i++
B loop
loop_end:
数组访问
; int arr[],R0 = 数组地址,R1 = 索引
; 读取 arr[index]
LDR R2, [R0, R1, LSL #2] ; arr[index]
; 写入 arr[index]
STR R2, [R0, R1, LSL #2] ; arr[index] = value