ARM的编程模型
ARM的编程模型
ARM 的编程模型指的是从程序员(特别是汇编程序员和编译器设计者)视角所看到的 ARM 处理器架构。它定义了程序员可以使用的资源、数据操作方式以及规则,主要包括:寄存器组、数据类型、内存访问方式、执行状态和异常处理。
这是一个结构化的总结,便于理解:
一、核心组成部分
1. 寄存器组
这是编程模型的核心,是 CPU 内部的高速存储单元,用于存放指令、数据和地址。
AArch32 (ARMv7 / ARMv8 AArch32 状态)
- 16个 32位 通用寄存器:R0 - R12, R13, R14, R15。
- R0-R12:通用目的寄存器,用于数据操作。
- R13 / SP:堆栈指针 (Stack Pointer),指向当前栈顶。
- R14 / LR:链接寄存器 (Link Register),用于保存子程序或函数调用的返回地址。
- R15 / PC:程序计数器 (Program Counter),指向下一条要执行的指令。
- 1个 32位 程序状态寄存器:CPSR (Current Program Status Register)
- 条件标志位 (Condition Flags):
N
(Negative),Z
(Zero),C
(Carry),V
(oVerflow)。这些位会根据算术或逻辑运算的结果自动改变,用于条件分支判断。 - 中断禁用位:
I
(IRQ disable),F
(FIQ disable)。 - 执行状态位:
T
(Thumb state bit),J (Jazelle state bit)。 - 处理器模式位:指定当前处于哪种模式(User, FIQ, IRQ, etc.)。
- 条件标志位 (Condition Flags):
- Banked Registers:在不同处理器模式下(如 FIQ, IRQ, SVC),某些寄存器(如 R13, R14)有自己独立的副本。这避免了在处理异常时破坏用户模式的寄存器状态,实现了快速上下文切换。
AArch64 (ARMv8 64位状态)
- 31个 64位 通用寄存器:X0 - X30。
- X0-X7:常用于参数传递和返回值。
- X8:间接结果寄存器。
- X9-X15:临时寄存器。
- X16-X17:内部过程调用临时寄存器。
- X18:平台保留寄存器。
- X19-X28:被调用者保存寄存器。
- X29:帧指针 (FP)。
- X30:链接寄存器 (LR)。
- 1个 64位 堆栈指针 (SP):专用寄存器,不再是通用寄存器之一。
- 1个 64位 程序计数器 (PC):无法被软件直接访问,只能通过特殊指令(如
BL
)修改。 - NZCV 寄存器:
PSTATE
(相当于 CPSR 的分布式视图)的一部分,独立保存条件标志位。
2. 数据类型与内存访问
- 数据类型:
- 基本类型:字节 (8-bit)、半字 (16-bit)、字 (32-bit)、双字 (64-bit)。
- 浮点数:半精度 (16-bit)、单精度 (32-bit)、双精度 (64-bit)。
- 内存访问:
- 对齐访问:强烈建议字(4字节)访问在4字节对齐的地址上,双字在8字节对齐的地址上,否则可能影响性能或导致异常。
- 端序 (Endianness):ARM 处理器通常为小端序 (Little-Endian),但许多架构也支持可配置的端序或大端序(BE8)。
3. 执行状态与异常级别 (ARMv8-A)
- AArch64:64位执行状态。
- 提供 31 个 64 位通用寄存器。
- 使用异常级别 (EL0 - EL3) 来定义特权级别,替代了传统的处理器模式概念。
- AArch32:32位执行状态,提供与 ARMv7-A 的兼容性。
- 运行传统的 ARM/Thumb 指令。
- 仍然使用传统的处理器模式(User, FIQ, IRQ, etc.)。
4. 操作模式 (AArch32)
- 用户模式 (User):非特权模式,运行应用程序。
- 特权模式:包括 FIQ, IRQ, Supervisor (SVC), Abort, Undefined 和 System 模式。用于运行操作系统和异常处理程序。
二、编程特点
-
加载/存储架构 (Load/Store Architecture):
- 这是 ARM 架构的一个基本原则。
- 数据处理指令(如 ADD, SUB)只能操作寄存器,不能直接操作内存中的数据。
- 必须使用专门的加载 (LDR) 指令将数据从内存读到寄存器,处理完后,再用存储 (STR) 指令将结果写回内存。
-
条件执行 (Conditional Execution):
- ARM 指令集中的大多数指令都可以条件化执行。
- 通过在指令后添加条件码后缀(如
ADDEQ
,BNE
),指令仅在 CPSR 中的条件标志满足指定条件时才会执行。 - 这可以减少分支指令的数量,提高代码密度和性能。
-
桶式移位器 (Barrel Shifter):
- 许多 ARM 数据处理指令(如 ADD, MOV)可以将一个操作数进行移位或循环移位后再参与运算,无需额外的时钟周期。
- 例如:
MOV R1, R0, LSL #2
将 R0 的值左移2位(即乘以4)后存入 R1。
-
Thumb / Thumb-2 指令集:
- Thumb:16位指令集,代码密度高,用于节省内存空间。
- Thumb-2:混合了 16 位和 32 位指令,在保持高代码密度的同时,提供了接近 ARM 32 位指令集的性能。是现代 ARM Cortex-M 等嵌入式处理器的默认指令集。
总结
ARM 的编程模型以其简洁、高效和灵活著称。其核心特点包括:
- 规整的寄存器文件和加载/存储架构。
- 强大的条件执行和集成桶式移位器,提高了指令效率。
- 通过 Banked Registers 实现高效的异常处理。
- 提供 Thumb 指令集以实现高代码密度。
- 在 ARMv8 中演进为 AArch64/AArch32 双执行状态和异常级别 (EL) 模型,以支持更复杂的应用场景(如服务器、虚拟化)。
理解 ARM 的编程模型是进行底层系统编程、驱动开发、性能优化和体系结构研究的基础。