ARM汇编基础(GNU风格)
ARM汇编基础(GNU风格)
指令格式
数据运算指令
位移指令
LSL指令
LSL(Logical shift Left) 逻辑左移
最高位移出,最低位补0
将操作数1寄存器中数据位移后移动到目标寄存器中
lsl r0, r0, #2
lsl r0, #2
LSR指令
LSR(Logical shift Right) 逻辑右移
最低位移出,最高位补0
将操作数1寄存器中数据位移后移动到目标寄存器中
lsr r0, r0, #2
lsr r0, #2
ASR指令
ASR(Arithmetic Shift Right) 算术右移
将操作数视为有符号补码表示的数
最低位移出,最高位用符号位补充
@ r0 #-4 0x ff ff ff fc -> #-2 0x ff ff ff fe
asr r0, r0, #2
ROR指令
ROR(Rotate Right) 循环右移
寄存器中数据二进制整体右移,最低为从最高位重新进入
@ r0 #0x00 00 00 B1
1011 0001
@ r0 #0x20 00 00 16
0010 0000 00 00 0001 0110
ror r0, r0, #3
计算指令
ADD指令
将操作数1加上操作数2的结果给目标寄存器
add r2, r0, r1
add r2, r0, r1 lsl #1
SUB指令
将操作数1减去操作数2的结果给目标寄存器
sub r0, r2, r1
sub r0, r2, r1 ,lsl #2
MUL指令
将操作数1乘以操作数2的结果存放在目标寄存器中
操作数1和操作数2必须是寄存器
目标寄存器不能与操作数1寄存器相同
mul r2, r1, r0
逻辑指令
AND指令
将操作数1和操作数2按位与的结果存放在目标寄存器中
@ r0 0b 0101 0101
@ r1 0b 1010 1010
and r2, r0, r1
ORR指令
将操作数1和操作数2按位或的结果存放在目标寄存器中
@ r0 0b 0101 0101
@ r1 0b 1010 1010
orr r2, r0, r1
EOR指令
将操作数1和操作数2按位异或的结果存放在目标寄存器中
@ r0 0b 0101 0101
@ r1 0b 1010 1010
eor r2, r0, r1
BIC指令
将操作数1和操作数2按位取反的结果再按位与存放在目标寄存器中
等价于操作数2指定为1的位对应在操作数1上清0
@ r0 0b 1110 0101
@ r1 0b 0101 0101
bic r2, r0, r1
数据转移指令
MOV指令
将操作数2直接搬移到目标寄存器中
mov r0, #1
将操作数1寄存器中数据位移后搬移到目标寄存器中
mov r0, r1, lsl #2
MVN指令
将操作数2按位取反后搬移到目标寄存器中
mvn r0, #0
MRS指令
将CPSR或SPSR寄存器中数据搬移到目标寄存器中
MRS r0, cpsr
MSR指令
将寄存器中数据搬移到CPSR或SPSR寄存器中
MSR cpsr, r0
数据比较指令
CMP指令
将操作数1和操作数2做差进行比较,比较的结果自动影响CPSR当前程序状态寄存器中的NZCV标志位
@ r0 #10
@ r1 #20
cmp r0, r1
程序跳转指令
B指令
将pc跳转到指定标签
跳转范围不超过32M
b label
BL指令
将pc跳转到指定标签,并将跳转前的pc中的值保存在lr寄存器中
跳转范围不超过32M
bl label
PC赋值跳转
使用LDR伪指令,将跳转目标地址直接写入pc寄存器中实现程序跳转
ldr pc, =label
内存访存指令
LDR指令
将内存地址中的值加载到目标寄存器中
ldr r0, [r1] @ 寄存器间接寻址
ldr r0, [r1, #4] @ 基址变址寻址,先变址,后寻址
ldr r0, r1, #4 @ 基址变址寻址,先寻址,后变址
ldr r0, [r1, #4]! @ 基址变址寻址,先变址,后寻址,自动更新r1
STR指令
将寄存器中数据写入指定地址内存
@ r1 0b 0001 0000
str r0, [r1] @ 寄存器间接寻址
@ r1 0b 0001 0000
str r0, [r1, #4] @ 基址变址寻址,先变址,后寻址
@ r1 0b 0001 0000
str r0, r1, #4 @ 基址变址寻址,先寻址,后变址
@ r1 0b 0001 0000
str r0, [r1, #4]! @ 基址变址寻址,先变址,后寻址,自动更新基址
STM指令
将多个寄存器中数据加载到一块内存地址中
@ r0 0b 0001 0000
stmia r0, {r1, r2, r3} @先存数,后递增变址
stmia r0, {r1-r3} @先存数,后递增变址
stmia r0!, {r1-r3} @先存数,后递增变址,自动更新基址
@ r0 0b 0001 0000
stmib r0, {r1, r2, r3} @先递增变址,后存数
@ r0 0b 0001 0000
stmda r0, {r1, r2, r3} @先存数,后递减变址
@ r0 0b 0001 0000
stmdb r0, {r1, r2, r3} @先递减变址,后存数
LDM指令
将一块内存地址中的数据加载到多个寄存器中
@ r0 0b 0001 0000
ldmia r0, {r1, r2, r3} @ 先取数,后递增变址
ldmia r0, {r1-r3} @ 先取数,后递增变址
ldmia r0!, {r1-r3} @ 先取数,后递增变址,自动更新基址
@ r0 0b 0001 0000
ldmib r0, {r1, r2, r3} @ 先递增变址,后取数
@ r0 0b 0001 0000
ldmda r0, {r1, r2, r3} @ 先取数,后递减变址
@ r0 0b 0001 0000
ldmdb r0, {r1, r2, r3} @ 先递减变址,后取数
STMFD指令
对栈sp操作前,必须初始化设置sp指针
规定使用满减栈方式进栈,先递减变址,后入栈存数
@ sp 0b 08010 0000
stmfd sp!, {r1-r3} @ 以sp作为满减栈栈顶指针,入栈,自动更新sp
LDMFD指令
对栈sp操作前,必须初始化设置sp指针
规定使用满减栈方式出栈,先出栈取数,后递增变址
@ sp 0b 08010 0000
ldmfd sp!, {r1-r3} @ 以sp作为满减栈栈顶指针,出栈,自动更新sp
伪指令
LDR伪指令-立即数
ldr r0, =0x12345678
- 汇编器主动在pc(考虑流水线影响)附近存放立即数
- 利用pc基址变址寻址方式,将立即数加载到寄存器中
LDR伪指令-标签
ldr r0, =label
- 汇编器主动在pc(考虑流水线影响)附近存放标签地址值
- 利用pc基址变址寻址方式,将标签地址值加载到寄存器中
ldr r0, label
- 当指定标签所在地址位于当前pc相对偏移范围内时
- 汇编器自动计算相对偏移值,并将pc与偏移值相加得到标签地址,再把标签地址中的数据加载到寄存器中
ADR伪指令
adr r0, label
- 当指定标签所在地址位于当前pc相对偏移范围内时
- 汇编器自动计算相对偏移值,并将pc与偏移值相加,得到标签地址放到寄存器中

浙公网安备 33010602011771号