1. ARM汇编异常处理机制解析
在嵌入式系统开发中,异常处理是保证系统可靠性的关键机制。ARM架构通过异常表(exception table)实现高效的错误处理流程,这套机制与常见的C++异常处理有本质区别。
1.1 异常表与unwind表原理
异常表是ARM架构中用于定位异常处理程序的专用数据结构,包含以下核心组件:
- 异常向量表:硬件定义的固定地址跳转表,包含复位、未定义指令、IRQ等入口
- unwind表:记录函数调用栈信息的元数据,包含:
- 栈帧指针位置
- 寄存器保存位置
- 栈调整量
当异常发生时,处理器会:
- 保存当前执行状态到SPSR
- 切换到对应异常模式
- 从异常向量表跳转到处理程序
- 通过unwind表回溯调用栈
1.2 编译器选项控制
armasm汇编器提供四个关键选项控制异常表生成:
assembly复制--exceptions ; 为所有函数生成异常表
--no_exceptions ; 完全禁用异常表生成
--exceptions_unwind ; 尽可能生成unwind表
--no_exceptions_unwind ; 强制所有函数使用nounwind表
实际开发中,典型使用场景包括:
- 实时系统内核:使用
--exceptions_unwind确保关键路径可回溯 - 性能敏感代码:使用
--no_exceptions_unwind避免元数据开销 - 混合编程环境:通过
.arm和.thumb区段分别控制
经验:在RTOS开发中,建议对任务调度器使用
--exceptions,对中断服务例程使用--no_exceptions_unwind
2. EHABI规范与栈帧约束
2.1 EHABI核心要求
ARM异常处理ABI(EHABI)第9.1节规定了栈帧必须满足的条件:
- 栈指针必须4字节对齐
- 帧指针(FP)必须指向有效的调用帧
- 每个PROC/ENDP包裹的函数必须包含完整的栈操作指令
- 非叶函数必须保存LR寄存器
典型合规栈帧示例:
assembly复制my_func PROC
PUSH {r4-r6, lr} ; 保
