现代计算机配备了完善的异常和中断处理系统。CPU内部设有异常检测和响应逻辑,外部设备接口则包含中断请求和控制逻辑,操作系统中集成了相应的异常/中断服务程序。这些硬件电路与软件程序紧密结合,共同完成异常和中断的处理过程。
5.5.1 异常和中断的基本概念
异常(也称内中断)是指CPU在执行指令过程中,由其内部检测到的同步事件,例如除零错误、非法操作码、页缺失等。这类事件由当前指令直接引发,具有确定性和可重现性。
中断(也称外中断)则是由外部设备(如I/O控制器)发起的异步事件,用于通知CPU外设状态发生变化(如数据就绪或传输完成)。中断的发生与当前指令无关,具有随机性。
两者的处理流程大致如下:当CPU执行用户程序的第 条指令时,若该指令触发异常,CPU通常会在其执行过程中或完成时立即响应;而外部中断则仅在第 条指令完整执行结束后才被检测(指令执行期间不会采样中断信号)。响应发生后,CPU暂停当前程序,保存现场,并转移至相应的服务程序。处理完成后,若事件可恢复,系统将通过执行异常或中断返回指令,恢复上下文并继续原程序:异常通常需重新执行第 条指令(例如缺页异常需在页面调入后重试访存操作),而中断则从第 条指令开始继续执行;若异常属于不可恢复的致命错误(如非法指令),操作系统将终止该用户进程。
异常和中断的处理流程大致相同,这也是为什么有些教材将它们统称为中断的原因。
5.5.2 异常和中断的分类
1. 异常的分类
异常是由CPU内部产生的意外事件,可分为硬故障中断和程序性异常。硬故障中断是由硬件逻辑功能出现异常引起的,如存储器校验错、总线错误等。程序性异常也称软件中断,是指在CPU内部因执行指令而引起的异常事件。如除零、溢出、断点、单步跟踪、非法指令、栈溢出、地址越界、缺页等。按异常发生原因和返回方式的不同,可分为故障、自陷和终止。
(1) 故障(Fault)
故障是指在指令启动之后、执行完成之前被检测到的异常事件。CPU在尚未提交该指令结果时即响应故障,并通常尝试在处理后重新执行同一条指令。典型的故障包括:指令译码时遇到非法操作码、访存时发生缺页、执行除法指令时发现除数为零等。对于可恢复的故障(如缺页),操作系统在处理完毕后(如将页面调入内存),然后返回并重新执行引发故障的指令;而对于不可恢复的故障(如非法指令、除零),则无法继续执行,通常会终止当前进程。
(2) 自陷(Trap)
自陷是一种预先安排的、用于主动转入操作系统内核的同步事件,也称陷阱或陷入。与故障不同,陷阱是在指令正常执行完毕之后才被触发的,因此CPU能够完整提交该指令的结果。典型应用包括:x86计算机架构中的断点调试与单步跟踪机制、系统调用指令(如syscall),以及MIPS架构中的条件自陷指令(如teq)。它就像程序中预先布设的一个“陷阱”:通过特殊指令(如断点指令)或特定控制标志(如单步跟踪标志)显式设置。当执行到此类指令时,CPU会根据其类型自动转移至相应的处理程序。处理完成后,CPU总是从自陷指令的下一条指令继续执行。
故障异常和自陷异常属于程序性异常(软件中断)。
(3) 终止(Abort)
终止是指在指令执行过程中发生严重的硬件故障(如控制器出错、存储器校验错、总线错误等),导致系统无法继续正常运行,程序因此被迫终止。此时,CPU会转移至相应的异常服务程序,通常用于记录错误信息或重启系统。与故障和自陷不同,终止异常并非由某条特定指令明确引发,其发生具有不可预测性,往往反映底层硬件或系统状态的严重损坏。
终止异常和外中断属于硬件中断。
2. 中断的分类
中断是指由外部设备或事件发起的异步请求,典型的中断源包括I/O设备(如键盘输入)、定时器(如周期性时钟中断)等。这些设备通过专用的中断请求信号线向CPU发出中断请求。CPU在每条指令执行结束后检查中断请求线;若检测到有效请求,则进入中断响应周期。
中断可分为可屏蔽中断和不可屏蔽中断。
(1) 可屏蔽中断
此类中断通过可屏蔽中断请求线INTR发送。CPU可通过中断控制器中的中断屏蔽寄存器选择性地屏蔽或允许特定中断源,被屏蔽的中断请求将不会传递至CPU。
(2) 不可屏蔽中断
此类中断通过专用的不可屏蔽中断请求线NMI发送,无法被软件屏蔽,用于处理高优先级事件,如电源掉电、内存校验错等。NMI确保CPU能及时响应这些关键故障。
尽管中断和异常的处理流程相似,但二者存在以下两个重要差异:
- 触发时机:异常(如缺页、除零等)由当前执行的指令直接引发,具有同步性;而中断由外部事件异步触发,与任何特定指令无关,且不会打断当前指令的执行。
- 检测机制:异常由CPU内部逻辑在指令执行过程中自动检测或由软件显式触发;中断则依赖外部硬件通过中断请求线通知CPU,再进一步确定中断源及类型。
此外,中断还可按其他维度分类:按服务程序入口地址的获取方式,分为向量中断(硬件直接提供服务程序入口地址)和非向量中断(通过软件轮询确定中断源);按是否允许嵌套处理,分为单重中断(服务期间禁止新中断)和多重中断(允许高优先级中断嵌套)。
5.5.3 异常和中断响应过程
当CPU在执行指令过程中检测到异常,或在指令边界处采样到中断请求时,将启动异常或中断响应过程。该过程指从事件发生到转移至相应处理程序之间的硬件自动操作序列,主要包括关中断、保存断点和程序状态、以及识别事件类型并转移至处理程序三个阶段。
(1) 关中断
为确保上下文保存的原子性,在响应异常或中断的初始阶段,CPU会自动屏蔽可屏蔽中断(通常通过清零标志寄存器中的IF位)。IF=0表示关中断,IF=1表示开中断。需要注意的是,不可屏蔽中断和部分高优先级异常仍可能在此期间发生,具体行为取决于体系结构设计。
(2) 保存断点和程序状态
为支持处理完成后正确返回原程序,CPU必须保存两类关键上下文信息:
断点(返回地址),对于异常通常为当前指令地址,对于中断则为指令执行完毕后的下一条指令地址;程序状态字(PSW),包含条件码、中断允许标志、特权级等运行状态。这些信息通常被压入内核栈,既保障了上下文的安全性,又天然支持中断与异常的嵌套处理。
(3) 识别事件类型并转移至处理程序
现代处理器普遍采用硬件向量机制(称为向量中断)来识别和响应异常与中断:每类事件都被分配唯一的类型号;系统初始化时,将对应服务程序的入口地址(称为中断向量)按类型号顺序填入中断向量表;当事件发生时,CPU自动获取类型号,并以此为索引直接访问向量表,获取目标地址并转移至相应处理程序,全程无须软件介入。
相比之下,早期系统常采用软件轮询方式(称为非向量中断):CPU响应请求后转移至统一入口,操作系统需要依次读取各设备的状态寄存器,通过查询确定中断源。该方式依赖软件判别、效率较低,现代系统已极少使用。
整个响应过程由硬件自动完成,具有高度原子性。响应结束后,CPU开始执行对应服务程序的第一条指令。后续处理逻辑(如缺页页面调入、系统调用分发等)由操作系统内核的软件实现,因此,完整的异常与中断处理是软硬件紧密协同的结果。
