算术运算
指令 | 功能说明 | 示例代码 |
---|
ADD | 加法(寄存器/立即数) | ADD R0, R1, #10 加 R1 和 10 |
ADC | 带进位加法(处理溢出或链式加法) | ADC R0, R1, R2 |
SUB | 减法 | SUB R0, R1, #5 |
SBC | 带借位减法 | SBC R0, R1, R2 |
RSB | 反向减法(结果 = 操作数2 - 操作数1) | RSB R0, R1, #10 |
MUL | 无符号乘法 | MUL R0, R1, R2 |
MLA | 乘法并累加 | MLA R0, R1, R2, R3 |
逻辑运算
指令 | 功能说明 | 示例代码 |
---|
AND | 按位与 | AND R0, R1, #0xFF |
ORR | 按位或 | ORR R0, R1, #0x1 |
EOR | 按位异或 | EOR R0, R1, R2 |
BIC | 清除指定位(按位与取反) | BIC R0, R1, #0xFF00 |
MOV | 将值加载到寄存器 | MOV R0, #5 |
MVN | 按位取反后加载 | MVN R0, #0x0F |
ASR | 算术右移(带符号扩展) | ASR R0, R1, #2 |
LSR | 逻辑右移 | LSR R0, R1, #1 |
LSL | 逻辑左移 | LSL R0, R1, #1 |
ROR | 循环右移 | ROR R0, R1, #3 |
比较和测试
指令 | 功能说明 | 示例代码 |
---|
CMP | 比较两个值(设置条件标志位) | CMP R0, #10 |
CMN | 比较两个值的相反数(类似加法) | CMN R0, #10 |
TST | 按位与后测试(仅影响标志位) | TST R0, #0x1 |
TEQ | 按位异或后测试(仅影响标志位) | TEQ R0, R1 |
2. 数据加载/存储指令
用于内存与寄存器之间的数据传递。
指令 | 功能说明 | 示例代码 |
---|
LDR | 从内存加载数据到寄存器 | LDR R0, [R1] |
LDRB | 从内存加载一个字节到寄存器 | LDRB R0, [R1] |
LDRH | 从内存加载半字到寄存器 | LDRH R0, [R1] |
STR | 将寄存器数据存储到内存 | STR R0, [R1] |
STRB | 将寄存器数据中的一个字节存储到内存 | STRB R0, [R1] |
STRH | 将寄存器数据中的半字存储到内存 | STRH R0, [R1] |
LDM | 从内存加载多个寄存器值(块传输) | LDM R1!, {R2, R3, R4} |
STM | 将多个寄存器值存储到内存(块传输) | STM R1!, {R2, R3, R4} |
PUSH | 将寄存器值压入堆栈(相当于 STMFD ) | PUSH {R4, LR} |
POP | 将堆栈值弹出到寄存器(相当于 LDMFD ) | POP {R4, PC} |
3. 分支指令
用于实现程序流程控制(跳转与分支)。
指令 | 功能说明 | 示例代码 |
---|
B | 无条件跳转 | B label |
BL | 带链接的跳转(调用子函数) | BL subroutine |
BX | 跳转到指定地址(支持切换到 Thumb 模式) | BX R0 |
BEQ | 条件跳转(相等) | BEQ label (当 Z=1 时跳转) |
BNE | 条件跳转(不相等) | BNE label (当 Z=0 时跳转) |
BGT | 条件跳转(大于) | BGT label (当 N=V 且 Z=0) |
BLT | 条件跳转(小于) | BLT label (当 N≠V) |
BGE | 条件跳转(大于等于) | BGE label (当 N=V) |
BLE | 条件跳转(小于等于) | BLE label (当 Z=1 或 N≠V) |
4. 系统控制指令
涉及 CPU 模式切换、异常处理和状态操作。
指令 | 功能说明 | 示例代码 |
---|
SWI | 软件中断 | SWI #0 |
MRS | 从 CPSR/SPR 中读状态寄存器 | MRS R0, CPSR |
MSR | 将值写入 CPSR/SPR | MSR CPSR, R0 |
NOP | 无操作(通常用于填充或延迟) | NOP |
5. 条件执行
ARM 指令的一个显著特点是支持条件执行。大部分指令后可以附加条件码。
条件码 | 说明 |
---|
EQ | 等于(Z=1) |
NE | 不等于(Z=0) |
GT | 大于(N=V 且 Z=0) |
LT | 小于(N≠V) |
GE | 大于等于(N=V) |
LE | 小于等于(Z=1 或 N≠V) |
常用伪指令
伪指令 | 解释 | 用法示例 |
---|
.data | 指定接下来的内容是数据段。 | .data
value: .word 0x1234 |
.text | 指定接下来的内容是代码段。 | .text
main: MOV R0, #0 |
.align | 将当前地址对齐到指定的字节边界(通常是 2、4、8)。 | .align 4 |
.global | 声明一个全局符号,使其在链接时对其他模块可见。 | .global main |
.word | 定义一个 32 位的整数(数据)。 | value: .word 0x12345678 |
.hword | 定义一个 16 位的整数(数据)。 | short_val: .hword 0x1234 |
.byte | 定义一个 8 位的整数(数据)。 | byte_val: .byte 0x12 |
.skip | 跳过指定字节数,填充为 0(也可以指定填充值)。 | .skip 8
.skip 4, 0xFF |
.ascii | 定义一个 ASCII 字符串,不包括字符串末尾的空字符 \0 。 | string: .ascii "Hello, ARM" |
.asciz | 定义一个以 \0 结尾的 ASCII 字符串。 | string: .asciz "Hello, ARM" |
.equ | 为常量赋值,相当于定义一个符号常量。 | SIZE .equ 0x100 |
.ltorg | 插入当前程序中的字面量池(通常用于加载常量到寄存器)。 | .ltorg |
.end | 标志程序结束。通常不是必需,但有时用于显式结束汇编代码。 | .end |
.set | 为符号分配一个值(类似于 .equ ,但可以多次修改)。 | var .set 0
.set var, 10 |
.space | 保留指定数量的字节空间。 | .space 16 |
.bss | 定义未初始化数据段(通常用于全局变量)。 | .bss |
.pool | 在当前位置插入字面量池,用于存放常量。 | .pool |
常用符号和修饰符
符号/修饰符 | 解释 | 用法示例 |
---|
@ | 注释符号,后面的内容被忽略。 | MOV R0, #0 @ Load 0 into R0 |
# | 表示立即数(常量)。 | MOV R0, #10 |
= | 用于加载常量值到寄存器,编译器自动管理字面量池。 | LDR R0, =0x12345678 |
: | 定义标签,用于标记位置,可供跳转指令使用。 | loop: SUBS R0, R0, #1 |
[] | 表示内存地址,通常用于加载或存储指令。 | LDR R1, [R0] |
! | 表示更新基址寄存器(在加载或存储指令中)。 | LDR R1, [R0], #4
LDR R1, [R0, #4]! |
{} | 用于块操作,例如将寄存器列表压栈或出栈。 | PUSH {R0, R1, LR} |
.L | 定义局部符号,通常在文件内唯一。 | .Lstart: MOV R0, #1 |
\ | 表示宏中传递的参数。 | .macro INC, reg
ADD \reg, \reg, #1 |