ARMv8 体系架构
文章目录
- [ARMv8 体系架构](#ARMv8 体系架构)
-
- [1. ARMv8 架构介绍](#1. ARMv8 架构介绍)
-
- [1.1 ARMv8 特色](#1.1 ARMv8 特色)
- [1.2 ARMv8 基本概念](#1.2 ARMv8 基本概念)
-
- [PE(Processing Element)](#PE(Processing Element))
- [ARMv8 是 RISC 架构](#ARMv8 是 RISC 架构)
- [1.3 执行状态](#1.3 执行状态)
- [1.4 指令集](#1.4 指令集)
- [1.5 系统寄存器](#1.5 系统寄存器)
- [1.6 支持的数据类型](#1.6 支持的数据类型)
- [1.7 异常等级](#1.7 异常等级)
- [1.8 通用寄存器](#1.8 通用寄存器)
- [2. 处理器状态](#2. 处理器状态)
-
- [2.1 条件标志位](#2.1 条件标志位)
- [2.2 异常掩码](#2.2 异常掩码)
- [2.3 运行状态控制位](#2.3 运行状态控制位)
- [3. 特殊寄存器](#3. 特殊寄存器)
1. ARMv8 架构介绍
1.1 ARMv8 特色
- 超大物理地址空间,支持 4GB 以上内存。
- 64 位宽的虚拟地址空间,支持 4GB 以上虚拟内存。
- 提供 31 个 64 位通用寄存器,可以减少对栈的使用,提高程序效率。
- 提供 16KB 和 64KB 的页面大小,降低 TLB 的未命中率,提高内存访问效率。
- 全新异常处理模型,有助于降低操作系统和虚拟化的复杂度。
- 全新的加载-获取、存储-释放指令,专为 C11/C++11/Java 等内存模型设计。
1.2 ARMv8 基本概念
PE(Processing Element)
- PE 是 ARM 架构规范中一个抽象的执行单元概念,指能够执行 ARM 指令并维护自身架构状态的逻辑实体。
- PE ≈ 处理器核心(core):一个物理 CPU 核心通常对应一个 PE。
ARMv8 是 RISC 架构
- 提供一组统一的通用寄存器。
- load/store 架构。
- 单一的地址模型。
1.3 执行状态
AArch64
- 提供 31 个 64 位通用寄存器。
- 提供 64 位的程序计数器(PC)、SP(栈指针)以及异常链接寄存器(ELR)。
- 提供 A64 指令集。
- 提供 ARMv8 异常模型,支持 4 个异常等级(EL0--EL3)。
- 提供 64 位的内存模型。
- 定义一组处理器状态(PSTATE)来记录 PE 的状态。
AArch32
- 提供 13 个 32 位通用寄存器,再加上 PC、SP、LR。
- 提供 A32 和 T32 两套指令集。
- 提供 ARMv7-A 异常模型,基于 PE 模式并映射到 ARMv8 的异常模型中。
- 提供 32 位的内存模型。
- 定义一组处理器状态(PPSR)来记录 PE 的状态。
1.4 指令集
ARMv8 根据不同的执行状态,提供了不同的指令集:
- A64 指令集:运行在 AArch64 模式下的指令。
- A32 指令集:运行在 AArch32 模式下的指令。
- T32 指令集:运行在 AArch32 模式下的 Thumb 指令,提供 16 位和 32 位两种指令集支持。
1.5 系统寄存器
系统寄存器提供控制和状态两种功能。
在 AArch64 模式下,系统会根据不同的异常等级,提供不同的变种:
<register_name>_EL<exception_level>- 例如
SP_EL0代表的是 EL0 异常等级下的栈指针寄存器,SP_EL1代表的是 EL1 异常等级下的栈指针寄存器,以此类推。
1.6 支持的数据类型
ARMv8 指令集支持多种数据类型,包括:
- byte(8 位)
- halfword(16 位)
- word(32 位)
- doubleword(64 位)
- quadword(128 位)
通用寄存器支持 32 位和 64 位两种宽度。
SIMD 和 FP 寄存器支持 128 位宽度。
1.7 异常等级

ARMv8 定义了 4 个异常等级(EL0--EL3),每个等级对应不同的权限和功能:
- EL3(Secure Monitor):始终运行在 Secure 状态,拥有最高特权级,负责安全世界与普通世界之间的切换,典型实现为 Trusted Firmware。
- EL2(Hypervisor):仅存在于 Non-secure 状态,用于虚拟化,管理多个 Guest OS,典型实现为 KVM、Xen。
- EL1(Operating System) :
- Secure EL1:运行可信操作系统(Trusted OS)。
- Non-secure EL1:运行普通操作系统内核(Rich OS),如 Linux Kernel、Windows Kernel。
- EL0(Application) :
- Secure EL0:运行可信应用(Trusted App)。
- Non-secure EL0:运行普通用户应用(App)。
注意:异常等级数字越小,特权越低;EL3 特权最高,EL0 特权最低。当系统未启用安全扩展时,EL3 可能不存在,整个系统仅运行在 Non-secure 的 EL2/EL1/EL0 下。
1.8 通用寄存器
AArch64 状态下,ARMv8 提供了 31 个 64 位通用寄存器,分别是 X0--X30。
AArch32 状态下,ARMv8 提供了 16 个 32 位通用寄存器,分别是 R0--R15。
- X0--X30 / R0--R12:通用寄存器
- PC:程序计数器
- SP:栈指针
- LR(R14):链接寄存器(AArch32)
2. 处理器状态
Armv7 里面使用 CPSR 寄存器来记录处理器状态,而 ARMv8 里面使用 PSTATE 寄存器来记录处理器状态。
2.1 条件标志位
ARMv8 中的条件标志位共有 4 个,合称 NZCV ,是 PSTATE 的一部分,用于记录算术/逻辑运算的结果特征。在 AArch64 中可通过 MRS NZCV / MSR NZCV 读写。
| 标志位 | 英文名称 | 中文名称 | 含义 | 典型设置条件 |
|---|---|---|---|---|
| N | Negative | 负数/符号标志 | 表示运算结果为负数(有符号视角) | 运算结果最高有效位为 1 时置 1 |
| Z | Zero | 零标志 | 表示运算结果为零 | 运算结果所有位均为 0 时置 1 |
| C | Carry | 进位/借位标志 | 表示无符号运算产生进位或借位 | 无符号加法产生进位时置 1;无符号减法中,未产生借位时置 1 |
| V | Overflow | 溢出标志 | 表示有符号运算结果溢出 | 正数加正数得负数,或负数加负数得正数时置 1 |
下图展示了算术/逻辑运算如何设置 NZCV 四个条件标志位:

补充说明:
- 对于大多数数据处理指令,只有带
S后缀的指令(如ADDS、SUBS、ANDS)才会更新 NZCV 标志位。 - 比较指令
CMP、CMN、TST也会更新标志位(它们本质上是目标寄存器为XZR的SUBS/ADDS/ANDS的别名)。 - 特殊指令如
CCMP(Conditional Compare)和CCMN同样会更新 NZCV 标志位。 - 条件跳转指令(如
B.EQ、B.NE、B.GT等)会根据 NZCV 的组合来决定是否跳转。 CMP本质上执行一次减法并更新标志位,但不保存运算结果。
2.2 异常掩码
在 ARMv8 中,PE 可以通过 PSTATE 中的 DAIF 位来屏蔽特定类型的异步异常(中断)和调试异常。DAIF 是 PSTATE 的 bit9:6,共 4 个标志位,每个位为 1 时表示屏蔽对应异常,为 0 时表示允许响应。
| 位 | 名称 | 全称 | 含义 |
|---|---|---|---|
| D | PSTATE.D | Debug mask | 调试异常屏蔽位。D=1 时屏蔽调试异常(如软件断点、硬件断点、观察点等)。 |
| A | PSTATE.A | SError mask | 异步错误屏蔽位。A=1 时屏蔽 SError(如外部总线错误、异步 Data Abort)。 |
| I | PSTATE.I | IRQ mask | 普通中断屏蔽位。I=1 时屏蔽 IRQ 中断。 |
| F | PSTATE.F | FIQ mask | 快速中断屏蔽位。F=1 时屏蔽 FIQ 中断。 |
下图展示了 PSTATE 中 DAIF 四个异常掩码位的布局:

如何设置和清除异常掩码
在 AArch64 中,可以通过以下系统寄存器指令操作 DAIF:
MSR DAIF, <Xt>:将 Xt 寄存器的值写入 DAIF 位,直接设置 4 个掩码位。MRS <Xt>, DAIF:读取当前 DAIF 位的值到 Xt 寄存器。MSR DAIFSet, #imm:将 imm 中为 1 的位对应的 DAIF 位置 1(屏蔽)。MSR DAIFClr, #imm:将 imm 中为 1 的位对应的 DAIF 位清 0(允许)。
其中 #imm 是一个 4 位立即数,分别对应 {D, A, I, F}。例如:
| 指令 | 作用 |
|---|---|
MSR DAIFSet, #0xF |
屏蔽所有调试异常、SError、IRQ、FIQ |
MSR DAIFClr, #0x3 |
清除 I 和 F 位,开放 IRQ 和 FIQ |
MSR DAIFSet, #0x2 |
设置 A 位,屏蔽 SError |
MSR DAIFClr, #0x4 |
清除 D 位,允许调试异常 |
使用场景
- 进入临界区 :在执行不可被打断的原子操作时,通常先
MSR DAIFSet, #0x3关闭 IRQ/FIQ,退出临界区后再MSR DAIFClr, #0x3恢复。 - 异常处理入口 :硬件在异常发生时会自动设置部分 DAIF 位(例如发生 IRQ 时会自动置 I=1,防止同级中断嵌套),异常返回时通过
ERET恢复原来的 PSTATE。 - 调试器控制:调试器可以通过设置 D 位来控制是否允许调试异常触发。
- SError 处理:在处理可能产生 SError 的代码路径时,通常需要小心处理 A 位,避免异步错误在不合适的时机进入。
注意事项
- DAIF 位只影响异步异常和部分调试异常,对于同步异常(如未定义指令、Data Abort、系统调用等)不起作用。
- 在更高的异常等级(如 EL3/EL2)中,可以通过系统寄存器进一步控制低异常等级的中断路由和屏蔽行为,例如
SCR_EL3、HCR_EL2等。 - 异常发生时,硬件会把旧的 PSTATE(包含 DAIF)保存到
SPSR_ELx中;异常返回时,ERET会从SPSR_ELx恢复 DAIF 等状态。
2.3 运行状态控制位
除了 NZCV 条件标志和 DAIF 异常掩码之外,PSTATE(以及保存它的 SPSR_ELx)还包含若干用于控制 PE 运行状态 的字段。这些字段决定了当前执行的异常等级、执行状态(AArch64/AArch32)、栈指针选择以及一些特殊控制功能。
| 字段 | 位域 | 名称 | 含义 |
|---|---|---|---|
| SS | PSTATE21 | Software Step | 软件单步控制位。用于调试,当 MDSCR_EL1.SS=1 且 PSTATE.SS=1 时,PE 在执行一条指令后会进入 Debug 状态或触发软件步进异常。异常进入时硬件会自动清除该位。 |
| IL | PSTATE20 | Illegal Execution State | 非法执行状态位。当 PE 进入非法执行状态(如在仅支持 AArch64 的 EL2/EL3 尝试执行 AArch32 代码)时,该位被置 1。IL=1 后,任何后续指令都会触发 Illegal Execution State 异常。 |
| nRW | PSTATE.M4 / SPSR.M4 | not Register Width | 执行状态选择位。0 表示 AArch64 ,1 表示 AArch32。该位只能在异常进入或异常返回时改变,不能由普通指令直接修改。EL2 和 EL3 固定为 AArch64,因此该位在这些 EL 上始终为 0。 |
| EL | PSTATE.M3:2 / SPSR.M3:2 | Exception Level | 当前异常等级。00=EL0,01=EL1,10=EL2,11=EL3。该位只能在异常进入或异常返回时改变。 |
| SP | PSTATE.M0 / SPSR.M0 / SPSEL | Stack Pointer Select | 栈指针选择位。在 EL1/EL2/EL3 时,0 表示使用 SP_EL0 ,1 表示使用当前 EL 对应的 SP_ELx ;在 EL0 时始终使用 SP_EL0。可通过 MSR SPSel, #imm 切换。 |
3. 特殊寄存器
除了通用寄存器和 PSTATE 以外,ARMv8 还定义了一系列特殊寄存器:
| 寄存器 | 说明 |
|---|---|
| XZR | 零寄存器,始终为 0。 |
| PC | 程序计数器。 |
| SP | 栈指针,根据当前 EL 和 SPSEL 位选择使用 SP_EL0 或 SP_ELx。 |
| SPSR | 保存处理器状态寄存器,只有在 EL1/EL2/EL3 时才有效。 |
| ELR | 异常返回寄存器,保存异常返回地址,只有在 EL1/EL2/EL3 时才有效。 |