ARM汇编学习

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 — 如果 R1R2 不相等,执行加法。
  • SUBEQ R3, R4, #5 — 如果相等,执行减法。

ARM汇编程序结构

ARM汇编程序由多个部分组成,常见的有:

  1. 头部:包括宏定义、引入库文件等。
  2. 数据部分:定义数据、字符串、常量等。
  3. 代码部分:包括指令执行逻辑,使用标签、跳转等控制程序流程。

例如:

1
2
3
4
5
6
7
8
9
.global _start

.section .text
_start:
MOV R0, #5 // 将 5 存入 R0
MOV R1, #3 // 将 3 存入 R1
ADD R2, R0, R1 // R2 = R0 + R1,即 5 + 3 = 8
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