ARM汇编学习
ARM寄存器
ARMv7(32位):
寄存器 |
角色 |
R0 - R3 |
用于传递前四个参数。最多四个参数会通过这些寄存器传递。 |
R4 - R11 |
用于存储其他局部变量,函数内部的计算可以使用这些寄存器。 |
R12 |
被称为“内存临时寄存器”,可以用于存储局部变量或函数计算结果。 |
R13 (SP) |
堆栈指针,指向栈的当前顶部,函数调用时,参数和返回地址可能会压栈。 |
R14 (LR) |
链接寄存器,用于存储返回地址,即调用函数后程序返回的位置。 |
R15 (PC) |
程序计数器,指向正在执行的指令地址。 |
程序状态寄存器(CPSR)
位数 |
名称 |
描述 |
31-28 |
M[4:0] |
当前处理器模式(Mode),包括用户模式、特权模式等。 |
27 |
T |
Thumb模式指示位,如果为1,则表示执行Thumb指令集。 |
26 |
F |
FIQ中断使能位,如果为1,表示使能快速中断。 |
25 |
I |
IRQ中断使能位,如果为1,表示使能普通中断。 |
24 |
A |
对齐异常使能位,如果为1,表示使能对齐检查。 |
23 |
E |
异常寄存器使能位,指定异常处理时是否使用扩展寄存器。 |
22-19 |
GE[3:0] |
符号扩展标志,用于浮点计算模式。 |
18 |
J |
指令缓存使能位,表示是否启用指令缓存。 |
17 |
Q |
异常标志位,表示某些条件是否满足,例如计算结果是否溢出。 |
16 |
V |
溢出标志位,标识算术操作是否发生溢出。 |
15-10 |
N, Z, C, V |
条件代码标志位,分别表示负标志、零标志、进位标志、溢出标志。 |
程序模式(M字段)
M值 |
模式 |
描述 |
0x10 |
User Mode |
用户模式,正常程序运行的模式。 |
0x1F |
System Mode |
系统模式,通常是内核模式或特权模式。 |
0x11 |
Supervisor Mode |
监控模式,操作系统核心模式。 |
0x13 |
Abort Mode |
异常模式,处理内存访问错误等异常情况。 |
0x17 |
IRQ Mode |
中断请求模式,用于处理中断。 |
0x1B |
FIQ Mode |
快速中断模式,处理快速中断请求。 |
特殊寄存器
寄存器名称 |
描述 |
SPSR |
保存异常状态寄存器,在进入异常模式时保存 CPSR 的内容。 |
FPSCR |
浮点状态控制寄存器,保存与浮点运算相关的状态。 |
ARMv8(64位,AArch64模式):
在ARMv8架构的64位模式(AArch64)中,寄存器传递参数的规则与32位有所不同。ARMv8增加了64位寄存器,并且使用 X
系列寄存器。
寄存器 |
角色 |
X0 - X7 |
用于传递前八个参数(64位寄存器)。 |
X8 |
被保留作为系统调用的返回值或特殊用途。 |
X9 - X15 |
用于存储局部变量或暂时的数据。 |
X16 - X18 |
用于编译器生成的临时数据(调用约定中可以使用)。 |
X19 - X28 |
用于传递更多参数或存储局部变量。 |
X29 |
帧指针(FP),指向当前栈帧的基地址。 |
X30 |
链接寄存器(LR),保存返回地址。 |
ARM指令
ARM指令类型
指令类型 |
示例 |
描述 |
数据处理 |
ADD , SUB , MUL |
算术操作,如加法、减法、乘法等。 |
数据传输 |
MOV , LDR , STR |
数据加载和存储指令,如 MOV 传送数据,LDR 从内存加载数据,STR 存储数据。 |
比较 |
CMP , TST |
比较两个寄存器的值并设置条件码,CMP 用于算术比较,TST 用于位与操作。 |
分支 |
B , BL , BX |
跳转指令,B 为无条件跳转,BL 为带链接的跳转(函数调用),BX 用于跳转到指定寄存器的地址。 |
条件执行 |
ADDNE , SUBEQ |
条件执行,指令后跟条件码,如 NE (不相等)、EQ (相等)。 |
位操作 |
AND , ORR , EOR |
位操作指令,AND 为按位与,ORR 为按位或,EOR 为按位异或。 |
移位 |
LSL , LSR , ASR , ROR |
移位指令,LSL 左移,LSR 右移,ASR 算术右移,ROR 循环右移。 |
栈操作 |
PUSH , POP |
栈操作指令,PUSH 将数据压栈,POP 从栈中弹出数据。 |
常用指令描述
指令 |
示例 |
描述 |
MOV |
MOV R0, #5 |
将常数 5 传送到寄存器 R0。 |
ADD |
ADD R1, R2, R3 |
将 R2 和 R3 相加并将结果存储到 R1。 |
SUB |
SUB R4, R5, #1 |
将 R5 减去常数 1,并将结果存储到 R4。 |
LDR |
LDR R0, [R1] |
从地址 R1 加载数据到寄存器 R0。 |
STR |
STR R0, [R1] |
将寄存器 R0 的值存储到地址 R1 。 |
CMP |
CMP R0, #10 |
比较 R0 和常数 10 的大小,设置条件码。 |
B |
B label |
无条件跳转到标签 label 。 |
BL |
BL function |
调用函数 function ,并保存返回地址到链接寄存器(LR)。 |
BX |
BX R0 |
跳转到 R0 寄存器所指示的地址。 |
条件执行
ARM汇编语言支持条件执行。每条指令可以根据上一条指令的条件码来决定是否执行。条件码包括:
条件码 |
描述 |
EQ |
相等 |
NE |
不相等 |
GT |
大于 |
LT |
小于 |
GE |
大于等于 |
LE |
小于等于 |
示例:
ADDNE R0, R1, R2
— 如果 R1
和 R2
不相等,执行加法。
SUBEQ R3, R4, #5
— 如果相等,执行减法。
ARM汇编程序结构
ARM汇编程序由多个部分组成,常见的有:
- 头部:包括宏定义、引入库文件等。
- 数据部分:定义数据、字符串、常量等。
- 代码部分:包括指令执行逻辑,使用标签、跳转等控制程序流程。
例如:
1 2 3 4 5 6 7 8 9
| .global _start
.section .text _start: MOV R0, #5 MOV R1, #3 ADD R2, R0, R1 MOV R7, #1 SWI 0
|
堆栈操作
在函数调用中,ARM使用堆栈来保存寄存器值、局部变量等。常见的堆栈指令:
指令 |
示例 |
描述 |
PUSH |
PUSH {R0, R1, R2} |
将 R0、R1、R2 压入栈中。 |
POP |
POP {R0, R1, R2} |
从栈中弹出 R0、R1、R2。 |
通过这些堆栈操作,程序可以在函数调用时保存现场,恢复现场。
1 2
| PUSH {R0, R1, R2} // 压栈,R2 -> R1 -> R0 POP {R0, R1, R2} // 弹栈,R0 -> R1 -> R2
|