vault backup: 2026-06-10 11:17:10

This commit is contained in:
2026-06-10 11:17:10 +08:00
parent 89e183aaaa
commit 788576ec4b
15 changed files with 3124 additions and 0 deletions
@@ -0,0 +1,201 @@
---
tags: [嵌入式系统, 复习, ARM架构]
create time: 2026-06-10 11:11
---
# ARM处理器架构
## 概述
本文档深入讲解ARM处理器的架构设计,包括命名规则、存储体系结构、流水线、寄存器组织、CPSR位域、工作模式以及FIQ/IRQ中断机制。ARM架构是嵌入式系统考试的重点内容。
## 正文
### 1. ARM概述
ARM(Advanced RISC Machines)是一系列**处理器核心**的名称,不是一家公司的名字。ARM公司采用**IP授权**模式——设计处理器核心,将设计方案授权给芯片厂商(如高通、三星、ST)进行制造。
ARM的核心特点:
- **RISC架构**(精简指令集计算机):指令数量少,指令长度固定,执行效率高
- **低功耗**:适合移动设备和嵌入式场景
- **IP授权模式**:ARM自己不生产芯片
### 2. ARM7TDMI命名规则
以经典的ARM7TDMI为例,其后缀含义如下:
| 后缀 | 全称 | 含义 |
|------|------|------|
| T | Thumb | 支持Thumb指令集(16位) |
| D | Debug | 支持JTAG调试 |
| M | Multiplier | 增强型乘法器 |
| I | ICE | 支持嵌入式ICE(In-Circuit Emulator) |
### 3. 冯·诺依曼 vs 哈佛架构
这是嵌入式系统的经典考点:
**冯·诺依曼架构**(ARM7采用):
- 指令和数据**共享**同一条总线和同一存储空间
- 不能同时取指令和读写数据
- 结构简单,成本低
**哈佛架构**(ARM9及以上采用):
- 指令和数据使用**独立的**总线和存储空间
- 可以同时取指令和读写数据
- 性能更高,但结构更复杂
> [!question] ARM7为什么选择冯·诺依曼架构?
> ARM7面向低成本嵌入式应用,冯·诺依曼架构只需一组总线,可以减少芯片面积和引脚数量,降低功耗和成本。对于ARM7的应用场景,性能已经足够。
### 4. ARM7三级流水线
ARM7处理器使用三级流水线:
| 阶段 | 名称 | 操作 |
|------|------|------|
| 1 | Fetch(取指) | 从存储器取出指令 |
| 2 | Decode(译码) | 解析指令含义,读取寄存器 |
| 3 | Execute(执行) | 执行运算,写回结果 |
在理想情况下,三级流水线使得每个时钟周期都能完成一条指令(吞吐率为1 CPI)。但当发生分支跳转时,流水线需要清空并重新填充,导致性能损失。
> [!tip] 流水线级数与PC值的关系
> 在ARM7三级流水线中,当前执行的指令地址是PC-8(因为PC已经预取了两条指令之后的内容)。这个细节在调试时很重要。
### 5. 寄存器组织
ARM7共有**37个**32位寄存器,但在任意时刻只能访问其中一部分:
- **User/SYS模式**:可访问**17个**(R0-R15 + CPSR)
- **其他特权模式**:可访问各自的SPSR,以及部分私有寄存器
#### 特殊功能寄存器
| 寄存器 | 名称 | 功能 |
|--------|------|------|
| R13 | SP(Stack Pointer) | 栈指针,指向当前栈顶 |
| R14 | LR(Link Register) | 链接寄存器,保存子程序返回地址 |
| R15 | PC(Program Counter) | 程序计数器,指向下一条要取的指令 |
| R12 | IP(Intra-Procedure-call) | 过程调用中间暂存寄存器 |
> [!question] 为什么每个异常模式都有自己独立的R13(SP)?
> 因为每个模式有自己的运行栈。如果所有模式共享一个SP,当中断发生时可能破坏正在使用的栈数据,导致系统崩溃。
### 6. CPSR位域详解
**CPSR**(Current Program Status Register,当前程序状态寄存器)是ARM中最关键的寄存器之一:
```mermaid
graph LR
subgraph CPSR["CPSR Bit Fields"]
direction LR
N["N[31]"] --> Z["Z[30]"] --> C["C[29]"] --> V["V[28]"]
V --> D["D[27]"] --> I["I[7]"] --> F["F[6]"] --> T["T[5]"]
T --> M["M[4:0]"]
end
style N fill:#ef9a9a
style Z fill:#ffcc80
style C fill:#fff176
style V fill:#a5d6a7
style I fill:#90caf9
style F fill:#90caf9
style T fill:#ce93d8
style M fill:#f48fb1
```
**条件标志位(N, Z, C, V)**:
| 标志位 | 位号 | 含义 |
|--------|------|------|
| N | [31] | **负数**标志:运算结果最高位为1时置位 |
| Z | [30] | **零**标志:运算结果为0时置位 |
| C | [29] | **进位**标志:加法产生进位或减法无借位时置位 |
| V | [28] | **溢出**标志:有符号运算溢出时置位 |
**控制位**:
| 标志位 | 位号 | 含义 |
|--------|------|------|
| I | [7] | IRQ禁止:置1时禁止IRQ中断 |
| F | [6] | FIQ禁止:置1时禁止FIQ中断 |
| T | [5] | Thumb状态:置1表示Thumb状态,置0表示ARM状态 |
| M[4:0] | [4:0] | 处理器模式选择位 |
> [!question] 如果CPSR的N=1、Z=0,这意味着什么?
> N=1表示上一次运算结果为负数,Z=0表示结果不为零。如果此时用BMI(Branch Minus)指令,分支将被执行,因为BMI条件是N=1。
### 7. SPSR
**SPSR**(Saved Program Status Register)保存的是进入异常模式**之前**的CPSR值。
当异常发生时,硬件自动将当前CPSR保存到对应异常模式的SPSR中。异常返回时,通过 `MOVS PC, LR` 指令将SPSR恢复回CPSR,从而恢复之前的状态。
> [!warning] User模式没有SPSR
> User模式不是异常模式,所以没有SPSR。如果需要保存User模式的状态,必须通过软件方式实现。
### 8. 七种工作模式
ARM处理器有7种工作模式:
```mermaid
graph TD
subgraph nonPriv["Non-Privileged"]
USR["USR - User Mode"]
end
subgraph priv["Privileged Modes"]
SYS["SYS - System Mode"]
SVC["SVC - Supervisor Mode"]
ABT["ABT - Abort Mode"]
UND["UND - Undefined Mode"]
IRQ["IRQ - IRQ Mode"]
FIQ["FIQ - FIQ Mode"]
end
SYS -.-> |"Same registers as USR"| USR
SVC --> |"Reset enters here"| SVC
style USR fill:#bbdefb
style SYS fill:#c8e6c9
style SVC fill:#ffcc80
style ABT fill:#ffab91
style UND fill:#ef9a9a
style IRQ fill:#ce93d8
style FIQ fill:#f48fb1
```
| 模式 | 编码 | 说明 | 进入方式 |
|------|------|------|----------|
| USR | 10000 | 用户模式,非特权 | 正常程序执行 |
| SYS | 11111 | 系统模式,特权 | 与USR共享寄存器 |
| SVC | 10011 | 管理模式 | **复位**、SWI |
| ABT | 10111 | 中止模式 | 存储器访问异常 |
| UND | 11011 | 未定义模式 | 未定义指令异常 |
| IRQ | 10010 | 中断模式 | IRQ中断 |
| FIQ | 10001 | 快速中断模式 | FIQ中断 |
几个关键点:
- **复位后进入SVC模式**,这是系统上电后的初始状态
- **USR不是异常模式**,因此没有SPSR
- **SYS模式**与USR共享寄存器,但具有特权权限
### 9. FIQ vs IRQ
| 比较维度 | FIQ | IRQ |
|----------|-----|-----|
| 优先级 | **更高** | 较低 |
| 私有寄存器 | R8-R14(7个) | R13-R14(2个) |
| 向量表位置 | 0x0000001C(末尾) | 0x00000018 |
| 响应速度 | 更快(寄存器保留多,切换少) | 较慢 |
| 嵌套 | 支持 | 支持 |
FIQ更快的原因:
1. 有更多的**私有寄存器**(R8-R14),中断处理时不需要保存/恢复通用寄存器
2. 向量表位于地址空间末尾,可以直接放置ISR代码,**无需跳转**
> [!question] 为什么FIQ的向量表放在0x0000001C(最后),而不是和其他异常一样在前面?
> 把FIQ的处理程序直接放在向量表位置0x0000001C开始的地方,可以省去一次跳转指令。因为从0x0000001C到中断向量表结束还有空间,足够放几条关键指令。
## 关联笔记
- [[嵌入式系统/试题册/index|试题册索引]]