计组与微机控制
4.0 异常模式
4.0 异常模式
引入:操作系统内核可以做:(我的操作系统笔记都有写为什么,比这个详细的多)
- 修改页表;
- 配置中断;
- 访问设备寄存器;
- 切换进程;
- 管理内存保护。
普通用户程序不能随意做这些事。
用户模式和特权模式:
处理器通常至少有:
- 用户模式;
- 特权模式/内核模式。
用户模式受限,特权模式权限高。
这种隔离保护系统不被普通程序破坏。
特权指令:
特权指令只能在特权模式下执行。
例如:
- 开关中断;
- 修改系统控制寄存器;
- 修改内存管理配置;
- I/O 控制;
- 进入低功耗或复位控制。
如果用户程序执行特权指令,会产生异常。
异常:
异常是打断正常程序执行的特殊事件。
来源可能是:
- 非法指令;
- 除零;
- 缺页;
- 访问越界;
- 系统调用;
- 外部中断。
异常会让 CPU 从当前程序转到异常处理程序。
异常模式
在编写ARM代码时,寄存器r13_SVC和r14_SVC仍被写作r13和r14。当切换到特权模式时,r13和r14在用户模式下的值将不可用。特权模式带有它自己的私有寄存器——r13和r14,这一机制意味着程序员不必在每次发生异常时保存r13和r14。异常可由内部和外部事件引起。外部事件是中断请求(IRQ),包括快速中断请求(FIQ)、复位以及页故障。内部异常则包括软件中断以及未定义的指令。


2.异常处理流程
一般流程:
异常发生 -> 保存现场 -> 切换模式 -> 找异常向量 -> 执行处理程序 -> 返回
和整理的 Cortex-M 异常流程一致。
系统调用是用户程序主动请求操作系统服务。
例如:
- 文件读写;
- 申请内存;
- 创建进程;
- 网络通信。
系统调用通常通过特殊指令触发异常,让 CPU 从用户模式进入内核模式。
Cortex-M 中类似思想是 `SVC`。
异常处理程序入口通常通过向量表找到。
向量表保存不同异常类型对应的处理程序地址。
这和 Cortex-M:
异常编号 x 4 + VT OR 基地址
的思路一致。
3.现场保存(也就是操作系统里面先在用户级syscall里面ecall到内核级,之后在trap模块里面mod.rs判断中断,也就是trap_handler处理中断之后在context.rs保存trapcontext之后跳转到syscall模块分发)
异常处理必须保存现场。
否则处理完异常后无法继续原程序。
现场包括:
- PC;
- 状态寄存器;
- 通用寄存器;
- 栈指针;
- 处理器模式信息。
Cortex-M 自动保存部分现场,其他由软件/编译器补充。
异常返回要恢复现场并回到被打断处。
普通函数返回只需回到调用点。
异常返回还要恢复:
- 特权级;
- 中断屏蔽状态;
- 程序状态字;
- 原来的 PC。
二.异常与操作系统

操作系统依赖异常机制实现:
- 系统调用;
- 定时器中断调度;
- 缺页处理;
- 设备中断;
- 保护机制。
没有异常机制,操作系统很难安全接管用户程序。

2.特权模式和异常总结
统一结论:
> 特权模式解决“谁有权做危险操作”,异常解决“发生特殊事件时如何安全切换控制流”。
和微机/STM32 联系:
- 8086/ARM 都有中断向量思想;
- Cortex-M 有 Handler 模式和 Thread 模式;
- SVC 是软件异常;
- HardFault 是错误异常;
- NVIC 管理外部中断;
- 异常进入和返回依赖栈保存现场。
3. 本章统一总结
栈帧、参数、递归和异常可以统一成一个模型:
正常函数调用:保存返回地址和局部状态,然后跳转
递归调用:同一个函数拥有多份栈帧
异常/中断:硬件强制保存现场并跳转处理程序
后续还会细化异常的讲解,在微机和异常专节里面,下一节risc和cisc
