Exception And Interrupt Handling
异常与中断的基本定义、分类和返回位置见 Exception-And-Interrupt-Brief。
中断响应与处理过程
一次中断处理可以分成两个阶段:
- 硬件阶段:CPU 完成中断响应,也常称为中断隐指令完成的工作。它会暂停现行程序,保存返回所需的断点信息,并把控制权转入操作系统内核中的处理程序入口。
- 软件阶段:操作系统内核或设备驱动执行中断服务程序。
中断处理的主线:
- 外部中断源提出中断请求。
- CPU 在当前指令执行结束后检查中断请求。
- 若满足响应条件,CPU 进行中断判优,选出要响应的中断源。
- CPU 执行中断隐指令:关中断、保存断点、切换到内核态,并引出内核中的中断服务程序。
- 内核态中断服务程序保存现场。
- 内核态中断服务程序完成具体服务。
- 中断服务程序恢复现场。
- 执行中断返回指令,回到原程序断点继续执行。
单重中断:中断返回指令会恢复中断前的 CPU 状态(包括中断允许位),因此开中断发生在步骤 8;处理期间全程关中断。
多重中断:在步骤 5–7 之间由软件显式开中断,使更高优先级的中断源可以打断当前服务程序。详见 [[#单重中断与多重中断]]。
中断隐指令不是指令系统里显式写出来的机器指令,而是由硬件自动完成的一组操作:关中断、保存断点、切换到内核态、引出中断服务程序。
后续的处理程序在操作系统内核中执行。
中断隐指令的主要任务:
| 任务 | 作用 |
|---|---|
| 关中断 | 防止保存断点、引出处理程序期间又被新的中断打断 |
| 保存断点 | 保存原程序的 PC,使中断处理完成后能返回原程序 |
| 转入内核态 | 使 CPU 从普通程序的执行状态转入内核态,执行内核代码、访问内核数据结构 |
| 引出中断服务程序 | 根据中断类型号或中断向量找到内核中的服务程序入口,并送入 PC |
| 概念 | 保存内容 | 主要由谁完成 |
|---|---|---|
| 保存断点 | PC,即原程序下一步应从哪里继续 | 中断隐指令(硬件) |
| 保护现场 | 通用寄存器、状态字、可能被服务程序破坏的运行环境 | 中断服务程序(软件) |
CPU 需要根据中断来源找到对应处理程序。常见做法是使用中断向量。这里的处理程序入口是操作系统内核中的入口,而不是用户程序里的普通函数入口。
基本关系:
$$
\text{中断类型号} \rightarrow \text{中断向量地址} \rightarrow \text{内核服务程序入口地址}
$$
中断类型号标识中断来源。中断向量表中保存各类中断服务程序的入口地址。CPU 响应中断时,通过中断类型号查表,把内核处理程序入口地址装入 PC,随后在内核态继续执行。
I/O 中断处理程序
I/O 中断服务程序会直接和 I/O 控制器打交道。一次典型 I/O 完成中断的处理过程:
- 从控制器读出设备状态。
- 判断 I/O 是否正常完成。
- 若异常,按错误原因处理,例如重试、报告错误、唤醒等待进程并返回错误。
- 若正常,读取数据寄存器或确认 DMA/通道已经完成传输。
- 更新内核中的 I/O 请求状态和缓冲区状态。
- 唤醒等待该 I/O 的进程,或把后续工作交给设备驱动、设备独立性软件继续处理。
中断处理程序位于操作系统内核中,在 I/O 软件层次里靠近硬件。它负责处理中断应答和硬件状态;更通用的 I/O 调度、设备分配、缓冲区管理通常在设备独立性软件层完成。
单重中断是在执行中断服务程序时不响应新的中断请求。它流程简单,但高优先级事件可能必须等待当前服务程序结束。
多重中断允许在中断服务程序中重新开中断,使更高优先级的中断源可以打断当前中断服务程序。多重中断需要处理中断优先级、屏蔽字和现场嵌套保存。
多重中断成立的关键条件:
- 中断服务程序中提前设置开中断。
- 高优先级中断源有权打断低优先级中断源。
- 使用屏蔽字控制哪些中断源可以继续申请。
- 每次嵌套都要保存对应现场和屏蔽字,返回时逐层恢复。
中断屏蔽
可屏蔽中断会受中断允许标志和屏蔽字控制。以常见约定为例:
IF=1:允许响应可屏蔽中断。IF=0:禁止响应可屏蔽中断。- 屏蔽字中
1表示屏蔽某个中断源,0表示该中断源可以正常申请。
不可屏蔽中断不受 IF 控制,通常用于电源故障等紧急事件。
屏蔽字中 1 越多,通常表示屏蔽范围越大。每个中断源对应的屏蔽字至少要能屏蔽自身,否则可能在处理中被同源中断反复打断。