异常和中断响应过程
前两节说清了”有哪些事件”和”事件属于哪一类”。这一节说从请求到返回,完整发生了什么。
教材在这里写得比较薄,但这一节实际上有三块独立的、都能出大题的内容:
- 中断隐指令——硬件那三件事,以及为什么必须是这三件、必须是这个顺序
- 判优(仲裁)——多个请求同时到达时选谁,三种电路各有各的代价
- 屏蔽字与嵌套——谁能打断谁,以及这件事为什么可以用软件改
第 2、3 块教材归在第 7 章 I/O 的程序中断方式里讲(7.3.2),但它们的原理属于本节,分开记会两边都记不牢。本节按完整机制写,第 7 章只补 I/O 特有的部分。
机制
一、响应的四个条件
四个条件缺一不可。 判断”某中断能否被响应”的题目,逐项核对即可。
注意 NMI 不受第二、三项限制(5.5.2),而异常不受第四项限制——异常在指令执行过程中就被发现,不必等指令结束。
二、中断隐指令:硬件的三件事
“隐”的意思是它没有操作码、不在主存里、程序里找不到它。 它是 CPU 自己的一段硬件动作。
| 顺序 | 动作 | 为什么必须 | 漏了会怎样 |
|---|---|---|---|
| 1 | 关中断(IF ← 0) | 保护接下来的保存动作不被打断 | 保存断点的过程中又来一个中断,第一个断点会被覆盖 |
| 2 | 保存断点(PC、PSW 入栈或存专用单元) | 将来要回来 | 回不去 |
| 3 | 引出中断服务程序(入口地址 → PC) | 转过去执行 | 不知道去哪 |
顺序不能换,而且”关中断在第一位”是有硬理由的。
保存断点需要若干个时钟周期(要访存)。如果在这期间响应了第二个中断,第二次隐指令又会去保存断点——而此时 PC 已经被第一次改成服务程序入口了,于是存下去的是错的,第一个程序永远回不来。关中断把这段窗口保护了起来。
这就是”临界区”这个概念在硬件上最早的形态——一段不能被打断的操作,靠”暂时关掉打断源”来保护。跨到 OS,临界区用的锁、以及内核里的关中断保护,是同一个思路的软件版本。
顺带解决一个高频疑问:既然关了中断,嵌套怎么发生? ——靠中断服务程序里主动开中断。硬件只保证”保存断点这段”不被打断,开中断的时机交给软件决定,见下面第四块。
三、中断向量:三个名字,别混
这三个词长得像,指的是三个不同层次的东西。
| 名字 | 是什么 | 类比 |
|---|---|---|
| 中断类型号 | 一个小整数,标识是哪个中断源 | 数组下标 |
| 中断向量地址 | 该中断向量在向量表中的地址 | 数组元素的地址 |
| 中断向量 | 中断服务程序的入口地址 | 数组元素的值 |
三步链条:
这个”用小整数查一张入口地址表”的模式,本章和上一章一共出现三次,形状完全相同:
三处都是”编号 → 入口地址”的一次映射,都靠一张预先建好的表,都省掉了一长串比较判断。 认出这个模式,三处的题目就是同一道题的三种外衣。
两种识别中断源的方式:
| 方式 | 怎么找到入口 | 特点 |
|---|---|---|
| 向量中断 | 硬件给出类型号,查向量表直接得入口 | 快,主流 |
| 查询中断 | 转入一段公共服务程序,软件逐个查设备状态位 | 慢,但硬件简单 |
“判断中断源”这一步归硬件还是软件,取决于用哪种方式——5.5.2 那张分工表里这一行之所以写着”两者皆可”,原因就在这里。
四、中断判优:三种仲裁方式
多个中断源同时提出请求时,选哪一个? 这就是判优(仲裁)。三种做法,代价各不相同。
(1)软件查询法
转入一段公共程序,按预定顺序逐个测试各设备的中断请求触发器,第一个测到的就是优先级最高的。
if (设备1请求) goto 服务1;
if (设备2请求) goto 服务2;
...
| 优先级由什么定 | 查询的先后顺序——写在程序里 |
| 改优先级 | 改程序即可,最灵活 |
| 硬件 | 几乎不需要 |
| 速度 | 最慢——设备多时要测很多次 |
(2)链式查询(菊花链,Daisy Chain)
所有设备串在一根”中断响应”信号线上,CPU 发出的响应信号从链头依次往下传。
规则:某设备若正在请求,就”吃掉”这个响应信号,不再往下传;若没请求,就原样传给下一个。
| 优先级由什么定 | 物理位置——离 CPU 越近优先级越高 |
| 改优先级 | 要重新接线,最不灵活 |
| 硬件 | 最省——只要一根链式信号线 |
| 速度 | 中等,信号要逐级传递 |
| 可靠性 | 差——链上任一设备的传递电路坏了,它后面全部失效 |
(3)独立请求方式(并行判优)
每个设备有自己独立的请求线和响应线,全部接到一个优先权编码器上,由硬件电路一次性选出优先级最高的。
| 优先级由什么定 | 编码器的逻辑——可做成可编程的 |
| 改优先级 | 若编码器可编程则可以改 |
| 硬件 | 最费—— |
| 速度 | 最快——一级组合逻辑出结果 |
三者对比
| 软件查询 | 链式查询 | 独立请求 | |
|---|---|---|---|
| 速度 | 最慢 | 中 | 最快 |
| 硬件成本 | 最低 | 低 | 最高 |
| 线数 | —— | 1 根链 | |
| 优先级改变 | 最容易(改程序) | 最难(改接线) | 中(可编程编码器) |
| 优先级取决于 | 查询顺序 | 物理位置 | 编码器逻辑 |
三者是一条”用硬件换速度”的连续谱,两端分别是”全软件、最慢最省”和”全硬件、最快最贵”。
关联对照:中断判优 / 总线仲裁
两套三方式是同构的——都在解决”多个请求者争一个资源,选哪个”:
中断判优 总线仲裁(6.2.1) 链式查询(菊花链) 链式查询(同名同构) 独立请求 独立请求(同名同构) 软件查询 计数器定时查询 前两种连名字都一样,判据也一样:链式查询靠物理位置定优先级、省线但不灵活;独立请求靠编码器、快但费线。
认出同构之后,两章只需记一套。 第 6 章那一套多出的”计数器定时查询”是链式与独立请求的折中——用计数器广播设备号,命中的设备应答。
五、响应优先级与处理优先级
这是本节最容易失分的一处辨析,也是”中断屏蔽字”存在的全部理由。
| 响应优先级 | 处理优先级 | |
|---|---|---|
| 决定什么 | 同时到达时先响应谁 | 嵌套时谁能打断谁 |
| 由什么决定 | 判优电路(上面三种之一) | 中断屏蔽字 |
| 能否用软件改变 | 不能 | 能 |
两者可以不一致,而且题目故意让它们不一致。
例:设备 A 的响应优先级高于 B。若把 B 的屏蔽字设成”不屏蔽 A”,而把 A 的屏蔽字设成”屏蔽 B”,那么:
- 同时请求时,先响应 A(响应优先级)
- B 正在服务时 A 来了,A 能打断 B(B 没屏蔽 A)
- A 正在服务时 B 来了,B 打不断 A(A 屏蔽了 B)
此时处理优先级 A > B,与响应优先级一致。 但只要把屏蔽字反过来设,就能做出”响应优先级 A>B 而处理优先级 B>A”的效果。
这就是为什么屏蔽字是软件可写的:判优电路是焊死的,但**“谁能打断谁”这件事和具体应用有关**,必须留给软件调整。
六、中断屏蔽字与嵌套
每个中断源配一个屏蔽字,进入它的服务程序时把这个屏蔽字送入屏蔽寄存器。屏蔽字中某位为 1 表示屏蔽对应的中断源。
屏蔽字表的读法(考试原样出现):
| 中断源 | 屏蔽 1 | 屏蔽 2 | 屏蔽 3 | 屏蔽 4 |
|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 1 |
| 2 | 0 | 1 | 1 | 1 |
| 3 | 0 | 0 | 1 | 1 |
| 4 | 0 | 0 | 0 | 1 |
三条读法规则:
- 对角线一定是 1——每个中断源都屏蔽自己,否则它的服务程序会被自己无限嵌套
- 某行 1 越多,这个中断源的处理优先级越高——它能屏蔽掉的别人越多
- 上表是”处理优先级 1>2>3>4”的标准形态;题目若给非三角形的屏蔽字表,就说明处理优先级被人为调整过
多重中断(嵌套)成立的两个条件:
- 中断服务程序中要有”开中断”指令——而且要放在保存现场之后
- 高优先级的中断源没有被当前屏蔽字屏蔽
第 1 条决定了服务程序的标准骨架:
中断服务程序:
保存现场(通用寄存器入栈) ← 此时仍是关中断
设置本中断源的屏蔽字
开中断 ← 从这里开始允许嵌套
...具体处理...
关中断 ← 保护恢复现场
恢复屏蔽字
恢复现场
开中断
IRET ← 恢复 PC 和 PSW
“保存现场时必须关中断、处理时可以开中断”——这个骨架和中断隐指令里”关中断放第一位”是同一个道理的延续:凡是会破坏”回得去”这个性质的操作,都必须在关中断状态下做。
单重中断就是把中间那条”开中断”去掉:服务程序全程关中断,任何新请求都要等它结束。
七、完整时序
flowchart TB A["指令执行完毕"] --> B{"有请求且允许?"} B -->|否| A B -->|是| C["判优:选出优先级最高的中断源"] C --> D["中断隐指令(硬件)<br/>①关中断 ②保存断点 PC/PSW ③入口地址→PC"] D --> E["保存现场(软件,关中断状态下)"] E --> F["设置屏蔽字 + 开中断"] F --> G["具体处理"] G --> H["关中断 + 恢复屏蔽字 + 恢复现场"] H --> I["开中断 + IRET"] I --> A classDef hw fill:#fecaca,stroke:#dc2626,stroke-width:2px classDef sw fill:#dbeafe,stroke:#2563eb,stroke-width:2px classDef judge fill:#f3f4f6,stroke:#6b7280 class C,D hw class E,F,G,H,I sw class B judge
红色是硬件,蓝色是软件,分界线正好在”保存断点”与”保存现场”之间(5.5.2)。
八、精确异常与流水线
上面所有讨论都默认”指令是一条一条执行完的”。流水线里这个前提不成立——异常发生时,流水线里同时有五条指令处于不同阶段。
精确异常(precise exception)的要求:
异常发生时,它之前的所有指令必须已经全部完成,它之后的所有指令必须一条都没有生效,就好像程序是严格顺序执行到那一点的。
实现手段:让流水线里该指令之后的所有指令作废(flush),之前的指令继续走完,然后再响应异常。
为什么必须精确:不精确的话,操作系统拿到的现场是”一半新一半旧”的,缺页之后根本无法正确重启那条指令(5.5.2 说故障要重执行当前指令)。虚拟存储器能工作,前提就是精确异常。
这也是 5.5.1 那条”指令边界响应保证了 ISA 抽象”在流水线上的延续——流水线破坏了物理上的指令边界,精确异常把逻辑上的指令边界重新造了出来。 详见 5.6.3。
边界
边界辨析:响应优先级 / 处理优先级
- 响应优先级:判优电路决定,软件不能改,管”同时来了先响应谁”
- 处理优先级:中断屏蔽字决定,软件可以改,管”嵌套时谁能打断谁”
二者可以不一致。这是本节最高频的辨析题。
边界辨析:中断向量 / 中断向量地址 / 中断类型号
- 中断类型号:小整数,标识中断源
- 中断向量地址:向量在表中的地址
- 中断向量:服务程序的入口地址(表项的值)
“中断向量 = 入口地址”这一条最常被记反成”中断向量 = 向量表的地址”。
边界辨析:关中断在隐指令中的位置
必须在保存断点之前。 否则保存断点这几个周期内若再来中断,第一个断点会被覆盖,程序永久回不去。
同理,恢复现场之前也要关中断。判据统一:凡是会破坏”回得去”的操作,都要在关中断状态下做。
层次辨析:三种判优方式
- 软件查询:靠查询顺序,最灵活最慢,几乎不用硬件
- 链式查询:靠物理位置,最省线,改优先级要重新接线,链上一环坏则后面全瞎
- 独立请求:靠优先权编码器,最快最费线(
根) 与总线仲裁的三方式同构,见 6.2.1。
边界辨析:单重中断 / 多重中断
差别只在服务程序里有没有”开中断”这条指令,以及位置在哪。
- 没有 → 单重,全程不被打断
- 有,且在保存现场之后 → 多重(嵌套)
开中断绝不能放在保存现场之前——那样嵌套会破坏还没存完的现场。
对照速查
| 动作 | 谁做 | 什么时候 |
|---|---|---|
| 关中断 | 硬件 | 隐指令第 1 步 |
| 保存断点(PC、PSW) | 硬件 | 隐指令第 2 步 |
| 送服务程序入口 | 硬件 | 隐指令第 3 步 |
| 保存现场(通用寄存器) | 软件 | 服务程序开头,关中断状态下 |
| 设置屏蔽字 | 软件 | 保存现场之后 |
| 开中断 | 软件 | 允许嵌套的起点 |
| 恢复现场 | 软件 | 关中断状态下 |
| 恢复 PC、PSW | 硬件(IRET 触发) | 最后 |
| 判优方式 | 优先级取决于 | 速度 | 线数 |
|---|---|---|---|
| 软件查询 | 查询顺序 | 慢 | —— |
| 链式查询 | 物理位置 | 中 | 1 根链 |
| 独立请求 | 编码器逻辑 | 快 |
| 屏蔽字表读法 | 含义 |
|---|---|
| 对角线为 1 | 每个中断源屏蔽自己 |
| 某行 1 的个数多 | 该中断源处理优先级高 |
| 标准下三角形态 | 处理优先级 = 编号顺序 |
| 非三角形态 | 处理优先级被人为调整过 |
考点
- 中断隐指令三件事 + 顺序:关中断、保存断点、送入口。关中断必须在最前,要能说出理由。
- 给屏蔽字表求 CPU 运行轨迹:本节最大的大题。画时间轴,逐个事件判断”当前屏蔽字允不允许”。
- 响应优先级 vs 处理优先级:判断某题改的是哪一个。改屏蔽字只能改处理优先级。
- 三种判优方式的对比:速度、线数、优先级如何决定、能否修改。
- 多重中断的两个条件:服务程序中开中断 + 未被屏蔽。
- 中断向量三个词的辨析:向量 = 入口地址。
- 精确异常:答异常之前的指令全部完成,之后的指令全部作废;它是虚拟存储器能工作的前提。
链接
- 🏠 返回总览:计算机组成原理第 5 章:中央处理器总览
- ⬅️ 上一节:5.5.2 异常和中断的分类
- ➡️ 下一节:5.6.1 指令流水线的基本概念
- 🔗 I/O 侧的程序中断方式:7.3.2 程序中断方式
- 🔗 总线仲裁的同构三方式:6.2.1 总线事务
- 🔗 “编号 → 入口表”的同一模式:4.3.2 选择语句(跳转表)
- 🔗 OS 视角:OS 1.3.2 中断和异常
- 📖 名词库:第 5 章名词库