本文声明:内容来源于网络,进行整合/再创作;部分内容由AI辅助生成。
核心寄存器功能
寄存器名称中的 _ELn 后缀表示:不同异常级别(EL0~EL3)对应不同的物理寄存器副本(如 SPSR_EL1 与 SPSR_EL2 是独立寄存器)。
|----------|----------------------------------------|--------------------------------------------|
| 寄存器 | 核心功能 | 特殊说明 |
| SPSR_ELn | 保存异常发生前的 PSTATE 状态,用于异常返回时恢复处理器状态 | 异常返回时若恢复的值与系统寄存器设置冲突,会产生错误 |
| ELR_ELn | 保存异常的返回地址,异常返回时恢复到 PC 寄存器 | 不同异常类型的返回地址规则不同(见下文) |
| X30 | 用于标准的子程序返回(与 RET 指令配合) | 执行 BL/BLR 分支指令时,自动更新为下一条指令的地址(子程序返回地址) |
| SP_ELn | 各异常级别专用堆栈指针(SP_EL0/1/2/3),指向专用堆栈地址 | 用于存储被异常处理程序破坏的寄存器值,便于返回前恢复 |
ELR_ELn 返回地址规则
|-------------------|-----------------------------------|----------------------------------------------|
| 异常类型 | 返回地址含义与特殊情况 | 典型场景 |
| 同步异常 (如 SVC 系统调用) | 通常为产生异常的那条指令后的下一条指令。 | 执行 SVC 指令时,可直接将 ELR_ELn 中的值返回给 PC,回到应用程序继续执行 |
| 同步异常 (如 SVC 系统调用) | 需重新执行异常指令时,可手动修改 ELR_ELn 指向异常指令本身 | 如数据访问异常,需修复后重新执行出错指令 |
| 异步异常 (如外部中断) | 指向尚未执行 / 未完全执行的第一条指令地址 | 中断触发时,处理器会暂停当前指令,返回时从该地址继续执行 |
| 异步异常 (如外部中断) | 必要时可修改 ELR_ELn(如减 4 / 8 字节) | 用于修正返回地址,确保指令执行流正确恢复 |
堆栈指针(SP_ELn)与切换
ARMv8 允许在不同异常级别下切换专用的堆栈指针,以提高安全性或隔离性。
1、专用堆栈设计
- 每个异常级别都有独立的 SP_ELn,用于指向专属堆栈地址;
- 堆栈用于临时保存被异常处理程序破坏的通用寄存器值,在返回前恢复,避免影响原始程序。
2、堆栈指针选择
|---------------------|-------------------------------------|----------------|
| 堆栈指针 | 典型用途 | 特点 |
| SP_ELn(如SP_EL1) | 用于存放可信的 、专用的堆栈(如内核的小型、常驻堆栈) | 保证始终有效,但空间可能有限 |
| SP_EL0 | 用于存放更大的 、临时的任务堆栈(如内核线程的大堆栈) | 空间大,但存在溢出的风险 |
3、堆栈切换方法
通过 MSR SPSel 指令实现堆栈指针的切换。
MSR SPSel, #0 ; 切换到 SP_EL0(通常用于用户态/任务堆栈)
MSR SPSel, #1 ; 切换到 SP_ELn(当前异常级别专用堆栈)
异常发生时的硬件自动操作
当异常事件触发时,处理器硬件会自动执行以下操作:
1、更新 SPSR_ELn:保存当前的 PSTATE 状态信息(如处理器运行模式、中断屏蔽位等),确保异常结束后准确恢复。
2、更新 PSTATE:使处理器进入新的执行状态(可能提高异常级别或保持不变)。
3、写入 ELR_ELn:将当前异常的返回地址自动写入该寄存器,为后续返回做准备。
异常返回流程(软件执行)
必须通过软件显式通知 处理器从异常返回,这是通过执行 ERET 指令完成的。
- 恢复异常前的 PSTATE:处理器从 SPSR_ELn 中读取保存的值,并将其写回 PSTATE。
- 恢复 PC 指针:处理器从 ELR_ELn 中读取保存的返回地址,将其写回程序计数器(PC),指令执行流切回到异常发生前的位置。
- 继续执行:处理器恢复到异常发生前的状态,并从正确的地址继续执行。
注意:
- 若 SPSR 中的状态与系统寄存器配置冲突,处理器会抛出错误;
- 可根据异常类型,手动修改 ELR_ELn 的值(如加减偏移)来调整返回地址。
异常处理流程整体逻辑

