程序中断方式
这一节和 5.5.3 讲的是同一件事的两侧。
王道教材把中断的完整机制——响应条件、中断隐指令、中断向量、判优电路、屏蔽字、嵌套——放在第 7 章这一节讲,而它们的原理属于第 5 章的 CPU。本笔记按原理归位:机制在 5.5.3 讲一次,这一节只讲它在 I/O 里的样子。
所以本节的定位是: 前半段快速对接 5.5.3 已有的结论,后半段写三样 5.5.3 没写的东西——中断识别的两条路线、中断服务程序的四段骨架、以及中断方式的性能计算。
机制
与 5.5.3 的分工
| 内容 | 在哪讲 |
|---|---|
| 中断的定义、为什么在指令边界响应 | 5.5.1 |
| 内中断/外中断分类、硬件软件分工 | 5.5.2 |
| 响应四条件、中断隐指令三件事、中断向量三个名字 | 5.5.3 |
| 判优三方式、响应/处理优先级、屏蔽字、嵌套、完整时序 | 5.5.3 |
| 中断请求的硬件来源(INTR/MASK 触发器) | 7.2.2 |
| 中断识别:向量中断与非向量中断 | 本节 |
| 中断服务程序的四段骨架 | 本节 |
| 中断方式的 CPU 占用率计算 | 本节 |
一次 I/O 中断的完整时间轴
flowchart TD A["CPU 写控制端口<br/>启动设备 + 开中断"] --> B["CPU 转去执行别的程序<br/>★ 与设备并行"] B --> C["设备完成,D 置 1<br/>→ INTR 置 1"] C --> D{"MASK = 0?"} D -->|"是"| E["向 CPU 发 INT 请求"] D -->|"否"| P["挂起,等解除屏蔽"] E --> F["CPU 在<b>当前指令结束</b>时<br/>检测到请求"] F --> G["中断判优:选出优先级最高者"] G --> H["中断隐指令(硬件)<br/>①关中断 ②保存断点 ③引出服务程序"] H --> I["中断识别:找到服务程序入口"] I --> J["中断服务程序(软件)<br/>①保护现场 ②<b>传送一个字</b><br/>③恢复现场 ④中断返回"] J --> K["返回断点,继续原程序"] classDef hw fill:#ffcdd2,stroke:#b71c1c,stroke-width:2px classDef sw fill:#c8e6c9,stroke:#1b5e20,stroke-width:2px classDef norm fill:#e3f2fd,stroke:#1565c0 classDef pend fill:#eceff1,stroke:#546e7a,stroke-dasharray:4 3 class C,D,E,F,G,H,I hw class A,J sw class B,K norm class P pend
红色的全是硬件自动完成,绿色的是软件。 分界线正好落在中断隐指令和中断服务程序之间——这是本节最重要的一条线。
注意 J 框里那句”传送一个字”:中断方式一次中断只传送一个字(或一小批),而不是一整块。 每传一个字就要中断一次、保护一次现场、恢复一次现场——这正是中断方式的开销所在,也是 DMA 存在的理由。
中断识别:向量中断与非向量中断
疑问点:中断识别的方法——向量中断和非向量中断分别是什么
先说这个问题在解决什么。
CPU 响应中断之后面临一个具体困难:它知道”有中断来了”,但不知道”是哪个设备来的”,因而不知道该跳到哪段服务程序去。中断识别就是回答”是谁”这一步。
两条路线,区别只在于”是谁”这件事由硬件查还是软件查:
向量中断 非向量中断 谁给出中断源身份 硬件(中断源自己送出中断类型号) 软件(服务程序逐个查状态位) 入口地址怎么来 查中断向量表,一步到位 先进统一的公共服务程序,再查 每个中断源 有各自的服务程序入口 共用一个总入口 速度 快,与中断源数量无关 慢,最坏要查遍所有设备 硬件成本 需要向量表和硬件排队电路 低 优先级怎么定 由判优电路(硬连线)决定 由查询顺序决定,改代码就能改 向量中断的三步链(详见 5.5.3 的”三个名字”):
非向量中断则是:
请 求 固 定 的 公 共 入 口 软 件 依 次 读 各 接 口 状 态 端 口 谁 的 就 转 谁
一处口径要统一。 5.5.3 里把这两种叫作「向量中断 / 查询中断」,教材和多数资料叫「向量中断 / 非向量中断」。这是同一个二分的两套叫法:
- 「非向量」是从结果说的——不用向量表。
- 「查询」是从手段说的——用软件轮询。
考试两种叫法都可能出现,认准”入口地址是硬件直接给的还是软件查出来的”这个判据就不会错。
一个容易被忽略的联系:非向量中断的”逐个查询”和 7.3.1 的程序查询方式,是同一个动作出现在两个不同的位置。
程序查询方式 非向量中断的识别 查什么 设备就绪了没有 是哪个设备发的中断 什么时候查 一直查,直到就绪 中断已经来了才查,查一遍就结束 代价 CPU 全程忙等 只在中断发生后查一次 所以”非向量中断 = 退化成查询方式”是错的。 它只是在识别这一步用了软件查询,而”等待设备就绪”这一步仍然是设备主动通知的——省下来的忙等时间一点没少。
中断服务程序的四段骨架
任何一个中断服务程序都是这四段,顺序固定:
| 段 | 做什么 | 谁做 |
|---|---|---|
| ① 保护现场 | 把要用到的通用寄存器压栈 | 软件(服务程序的第一批指令) |
| ② 中断服务 | 真正的设备处理:读/写一个数据端口,更新计数和地址 | 软件 |
| ③ 恢复现场 | 把通用寄存器出栈 | 软件 |
| ④ 中断返回 | 执行 IRET,恢复断点(PC、PSW)并开中断 | 硬件(由指令触发) |
边界辨析:保存断点 vs 保护现场
这两个词长得像,做的事也像,但由不同的角色在不同的时刻完成——这是本章被考得最狠的一对。
保存断点 保护现场 保存什么 PC、PSW(程序状态字) 通用寄存器( 、ACC 等) 谁做 硬件(中断隐指令的第二步) 软件(中断服务程序的第一段) 什么时候 进入服务程序之前 进入服务程序之后 能不能省 不能,省了就回不去 能省一部分——只需保存服务程序会用到的那些 恢复由谁 中断返回指令 IRET(硬件)服务程序末尾的出栈指令(软件) 为什么必须分成两段做?
因为硬件不知道服务程序会用到哪些寄存器。如果让隐指令把全部通用寄存器都压栈,大多数情况下都是白压——一个只读一字节的服务程序可能只动了两个寄存器。而 PC 和 PSW 是无论如何都必须立刻保存的:PC 马上就要被改成服务程序入口,晚一步就丢了。
所以分界线是:“马上就会被覆盖的,硬件立刻存;可能会被覆盖的,交给软件按需存。”
这个”硬件保证最小必需、软件负责按需扩展”的分工,与 5.5.3 里”硬件只保证保存断点这段不被打断,开中断的时机交给软件”是同一种设计哲学。
顺带解决嵌套:中断服务程序里如果要允许更高优先级中断打断自己,必须在①保护现场完成之后才能开中断。反过来,③恢复现场之前要先关中断。“开中断”和”关中断”这两条指令的位置,正好把②夹在中间——这是嵌套的两个条件之一,另一个(屏蔽字)见 5.5.3。
中断隐指令在 I/O 里的位置
疑问点:中断隐指令是什么
5.5.3 已经把它讲透了:它做三件事——①关中断 ②保存断点 ③引出中断服务程序,顺序不能换。 这里只补三点 I/O 视角的东西。
第一,“隐”到底隐在哪。 它没有操作码、不在主存里、程序清单上找不到它、汇编也写不出它。它是 CPU 在响应中断时自动执行的一组硬件操作,“指令”这个词只是借来描述”一组不可分割的动作”。
对比一下就清楚了:
普通指令 中断隐指令 有操作码吗 有 没有 存在主存里吗 是 不存在,是硬件时序 谁触发 程序顺序执行 中断响应 能否被程序员写出 能 不能 第二,它和中断识别的先后。 隐指令的第三步”引出中断服务程序”,本身就要用到中断识别的结果——向量中断下这一步是硬件查向量表,非向量中断下这一步是跳到公共入口。所以”中断识别”不是隐指令之外的第四件事,它就发生在第三步里面。
第三,它不负责什么。 隐指令不保护现场(那是服务程序做的)、不判优(判优在它之前)、不返回(返回是
IRET)。把这三件事划出去之后,隐指令就只剩那三步了,很难再记错。一句话:判优在前,隐指令居中,服务程序在后;隐指令是硬件与软件的交接点。
判优不是识别
这两个词在同一段流程里紧挨着出现,极易混。
| 中断判优(仲裁) | 中断识别 | |
|---|---|---|
| 回答什么问题 | 多个同时来,先响应谁 | 响应的这个,是谁发的 |
| 什么时候 | 响应之前 | 响应之后(隐指令第三步) |
| 前提 | 有多个中断源同时请求 | 哪怕只有一个中断源也要做 |
| 怎么做 | 链式查询 / 计数器定时查询 / 独立请求(5.5.3) | 向量中断 / 非向量中断(本节) |
| 结果 | 选出一个中断源 | 得到服务程序入口地址 |
顺序永远是:判优 → 响应 → 隐指令 → 识别 → 服务程序。
一个反例可以彻底分开它们:只有一个设备发中断时,不需要判优,但仍然需要识别——CPU 还是得知道跳到哪去。“只有一个中断源就不用识别”是错的。
再补一句,“多个请求者争一个资源”这个模式在本书里已经是第五次出现了:中断判优、总线仲裁、令牌环、以太网 CSMA/CD,加上下一节的 DMA 与 CPU 争总线。分界线仍然是”事前预约还是事后补救”——前四个都是事前预约,只有 CSMA/CD 是事后补救。
中断方式的 CPU 占用率
模板与 7.3.1 完全相同,只是把”每次传送的指令数”换成”一次中断的总开销”。
已知:设备传输率
算例。 磁盘传输率
把
这个数字就是 DMA 的动机:中断方式的开销与传送次数成正比,而传送次数 = 数据量 ÷ 每次传送量。 想降开销只有两条路——要么增大每次的传送量(成批中断),要么干脆别让 CPU 参与搬运(DMA)。
边界
| 说法 | 判断 | 理由 |
|---|---|---|
| ”中断方式下数据不经过 CPU” | ❌ | 仍由 CPU 在服务程序里搬 |
| ”中断隐指令负责保护现场” | ❌ | 它只保存断点(PC、PSW) |
| “保护现场由硬件完成” | ❌ | 软件,服务程序的第一段 |
| ”只有一个中断源就不需要中断识别” | ❌ | 仍需要,识别与判优是两回事 |
| ”非向量中断退化成了程序查询方式” | ❌ | 只在识别这一步查,等待仍是设备通知 |
| ”向量中断的优先级可以由软件修改” | ❌ | 由判优电路定;非向量中断的优先级才能靠改查询顺序修改 |
| ”中断向量就是中断服务程序的入口地址” | ✅ | 三个名字见 5.5.3 |
| ”中断向量地址就是中断服务程序入口地址” | ❌ | 它是向量表里那一项的地址,差一次访存 |
| ”中断服务程序里必须先开中断才能保护现场” | ❌ | 反了:先保护现场,再开中断 |
| ”中断方式提高了数据传输率” | ❌ | 提高的是 CPU 利用率 |
对照速查
| 阶段 | 谁做 | 做什么 |
|---|---|---|
| 判优 | 硬件 | 多个中选一个 |
| 响应 | 硬件 | 指令结束时检测到 |
| 中断隐指令 | 硬件 | 关中断 → 保存断点 → 引出服务程序 |
| 识别 | 硬件(向量)/ 软件(非向量) | 找到入口地址 |
| 服务程序 | 软件 | 保护现场 → 服务 → 恢复现场 → 返回 |
| 识别方式 | 入口怎么来 | 优先级由谁定 |
|---|---|---|
| 向量中断 | 硬件查向量表 | 判优电路,硬连线 |
| 非向量中断 | 软件查状态位 | 查询顺序,软件可改 |
考点
- 保存断点 vs 保护现场——本章第一高频,硬件/软件、之前/之后、PC-PSW/通用寄存器三组对照。
- 向量中断与非向量中断的六点对照。
- 判优与识别的区分,尤其”只有一个中断源也要识别”。
- 中断向量、中断向量地址、中断类型号三者的层次(5.5.3)。
- 中断方式 CPU 占用率计算,以及”增大每次传送量能降开销”这一推论。
链接
- 🏠 返回总览:计算机组成原理第 7 章:输入/输出系统总览
- ⬅️ 上一节:7.3.1 程序查询方式
- ➡️ 下一节:7.3.3 DMA 方式
- 🔑 完整中断机制:5.5.3 异常和中断响应过程
- 🔗 中断请求的硬件来源:7.2.2 I/O 接口的基本结构
- 🔗 为什么在指令边界响应:5.5.1 异常和中断的基本概念
- 💻 OS 对应:OS 5.1.2 I/O 控制方式
- 📖 名词库:第 7 章名词库