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与偏移值相加,得到标签地址放到寄存器中
posted @ 2025-12-26 10:55  L-ZH  阅读(0)  评论(0)    收藏  举报