1. 异常分析流程
1.1. 流程说明
1.1.1. 确定异常之前的状态
进入异常时,处理器会拦截写入LR寄存器的值,把PC值替换为EXC_RETURN,EXC_RETURN各位段定义如下:
- Bit[31:28]:固定为0xF
- Bit[27:5]:保留位,软件必须置 1(SBOP:Software Bit One Policy,软件置 1 规则)。若向该区域任意位写入 0 以外的值,行为不可预测(UNPREDICTABLE)。
- Bit[4:4]:处理器无浮点扩展单元 FP 时,软件必须置 1。若向该位写入 0 以外的值,行为不可预测。处理器无浮点扩展单元 FP 时,用于标识本次异常的栈帧是否分配了浮点状态存储空间:0,栈帧分配了浮点上下文存储空间。
- Bit[3:0]:定义异常返回所需执行的硬件行为,对应表格:
-
表1,无浮点单元的内核
-
表2,带浮点单元的内核
两张表格统一遵守以下规则:
- 表格未列出的 EXC_RETURN 数值均为保留值,对应内核不可使用;
- 表格中「Return stack(返回堆栈)」列代表:异常返回流程中,处理器用于恢复现场上下文的堆栈;同时也是异常退出后程序运行所使用的堆栈。
-
表1:无浮点扩展内核的异常返回行为 EXC_RETURN 定义
| EXC_RETURN | 返回到 | 返回的栈 |
|---|---|---|
| 0xFFFFFFF1 | Handler Mode(异常处理模式) | Main(主堆栈 MSP) |
| 0xFFFFFFF9 | Thread Mode(线程模式) | Main(主堆栈 MSP) |
| 0xFFFFFFFD | Thread Mode(线程模式) | Process(进程堆栈 PSP) |
表2:带浮点扩展内核的 EXC_RETURN 异常返回行为定义
| EXC_RETURN | 返回到 | 返回的栈 | 栈帧类型 |
|---|---|---|---|
| 0xFFFFFFE1 | Handler Mode(异常处理模式) | Main(主堆栈 MSP) | 扩展栈帧 Extended |
| 0xFFFFFFE9 | Thread Mode(线程模式) | Main(主堆栈 MSP) | 扩展栈帧 Extended |
| 0xFFFFFFED | Thread Mode(线程模式) | Process(进程堆栈 PSP) | 扩展栈帧 Extended |
| 0xFFFFFFF1 | Handler Mode(异常处理模式) | Main(主堆栈 MSP) | 基础栈帧 Basic |
| 0xFFFFFFF9 | Thread Mode(线程模式) | Main(主堆栈 MSP) | 基础栈帧 Basic |
| 0xFFFFFFFD | Thread Mode(线程模式) | Process(进程堆栈 PSP) | 基础栈帧 Basic |
1.1.2. 分析异常现场
处理进入异常时,会进行一次压栈操作。根据EXC_RETURN的值的不同,会压入不同的栈帧。如果处理器有FPU,有可能压入扩展帧,如果没有FPU,只会压入标准帧,参考表1和表2。从栈帧中的RetuenAddress(就是进入异常之前的PC),再结合MAP文件(如果有条件可以使用反汇编文件),基本可以确定异常发生的位置。
| 图1:标准帧 | 图2:扩展帧 |
|---|---|
![]() | ![]() |

