Appearance
程序查询与中断驱动I/O
考情分析
两条主线:中断响应过程(关中断→保存断点→识别中断源→转中断服务程序)要能默写并说清每步由硬件还是软件完成;程序查询和中断方式的 CPU 时间占用率要会算。
大纲定位
考纲第六章(三)「I/O 方式」第 1、2 条:程序查询方式、程序中断方式(中断的基本概念、中断响应过程、中断处理过程、多重中断和中断屏蔽的概念)。
要求到什么程度:能默写中断响应与处理的完整步骤并分清硬件/软件分工,能做屏蔽字与嵌套顺序的走查,能算 CPU 时间占用率。
程序查询方式
工作原理
CPU 通过不断读取设备状态端口来判断设备是否就绪,就绪后再进行数据传输。
开始:
CPU 向设备发出启动命令
循环:
读取状态端口
if (设备忙)
goto 循环 // 忙等待
else
传输一个字/字节数据
if (传输未完成)
goto 循环
else
结束性能分析
在设备准备数据期间,CPU 全部时间都消耗在轮询上——设备越慢,浪费越多。这是程序查询方式的根本缺陷。
具体怎么算 CPU 占比,见下文「例题」一节——先判是独占查询还是定时查询,两种模型公式不同。
适用场景
- I/O 操作很少且简单的嵌入式系统
- 对实时性要求极高、不能有中断延迟的特殊场合
- 设备速度与 CPU 速度差异不大时
中断驱动方式
基本思想
CPU 发出 I/O 命令后不再等待,转去执行其他程序。当设备完成操作后,通过中断请求通知 CPU,CPU 暂停当前程序,执行中断服务程序完成数据传输。
中断的分类
| 类型 | 来源 | 举例 |
|---|---|---|
| 外中断(硬件中断) | CPU 外部设备 | I/O 完成、定时器、键盘 |
| 内中断(异常) | CPU 内部 | 见下面三类 |
I/O 中断属于外中断。内中断还要再分三类——判断题常拿第三类设陷阱:
| 内中断子类 | 触发原因 | 举例 |
|---|---|---|
| 故障(fault) | 指令执行中可恢复的问题 | 缺页、段错误 |
| 终止(abort) | 不可恢复的硬件错误 | 校验错、总线错 |
| 陷阱(trap)/自愿中断 | 程序主动执行特定指令请求服务 | 系统调用(访管指令)、断点指令 INT 3、溢出自陷 |
编者注(易错):"执行断点指令"属于陷阱,是内中断(异常),不是外部中断。判断题给一串事件让你挑"哪个是外部中断",断点指令、系统调用、除零都要排除——它们全是当前程序自己引发的。判据是:这件事是不是由正在执行的这条指令引起的?是 → 内中断;不是(来自 CPU 之外)→ 外中断。
中断响应过程
什么时候检测——这一条是判断题的落点:
CPU 在每条指令执行结束时才去采样中断请求信号,不是在指令中间随时响应。
为什么必须在指令边界:只有一条指令完整执行完,PC 和 PSW 才处于一个干净、可恢复的状态;在指令中途打断,保存的断点无法保证返回后能正确接着跑。
由此得到一条对照:
| 检测时刻 | 与指令的关系 | |
|---|---|---|
| 中断(外部/异步) | 指令执行结束时 | 与当前指令无关,来自外设 |
| 异常(内部/同步) | 指令执行过程中 | 由当前指令自己引发(除零、缺页、非法指令) |
所以"外设一发中断请求 CPU 就立即暂停当前指令"是错的——要等这条指令做完。
当 CPU 检测到中断请求且允许响应时,执行以下步骤(由硬件自动完成):
- 关中断:将中断允许标志 IF 置 0,防止响应过程中被其他中断打断
- 保存断点:将当前 PC(和 PSW)压入栈,记录返回地址
- 识别中断源:确定是哪个设备发出的中断
- 转中断服务程序:将中断服务程序的入口地址送入 PC
上述硬件自动完成的步骤统称为中断隐指令——它不是指令系统中的一条真实指令,而是硬件在中断响应时自动执行的一系列操作。
编者注(外延口径):中断隐指令的三件核心事是 关中断、保存断点、送中断服务程序入口地址。上面第 3 步「识别中断源」是"送入口地址"的前置动作(要先知道是谁中断了,才知道该送哪个入口),不同教材有的把它单列、有的并进第 4 步。卷面按三件事答最稳:关中断 → 保存断点 → 送入口地址。
中断服务程序的执行过程(由软件完成):
- 保护现场:保存通用寄存器等 CPU 状态
- 中断服务:执行实际的 I/O 数据传输
- 恢复现场:恢复之前保存的寄存器
- 开中断:把 IF 置回 1
- 中断返回:执行中断返回指令(如 IRET),恢复 PC 和 PSW
编者注("开中断"的位置是考点):它必须放在恢复现场之后、中断返回之前。
- 放在恢复现场之前:恢复寄存器的过程可能被新中断打断,现场就乱了
- 完全不放:靠 IRET 恢复 PSW 会把 IF 一起恢复——但这依赖具体机器,统考按"服务程序末尾显式开中断"作答
完整顺序:保护现场 → 中断服务 → 恢复现场 → 开中断 → 中断返回。选择题给你打乱的步骤让你排序,这一步的位置就是区分点。
中断源识别
两种方式:
软件查询法:CPU 逐一检查各设备的中断标志位,先查到的先处理。
硬件向量法(中断向量表):每个中断源有唯一编号,对应中断向量表中的一个表项,表项存放中断服务程序的入口地址(即中断向量)。
使用中断向量表的方式称为向量中断(响应速度快,硬件自动定位 ISR 入口);使用软件查询的方式称为非向量中断(速度慢,需逐一检查中断标志)。现代机器普遍采用向量中断。
信号方向别搞反——这是选择题的一个落点:
| 信号 | 方向 | 作用 |
|---|---|---|
| INTR(中断请求) | 外设 → 中断控制器 → CPU | 请求中断服务 |
| INTA(中断响应) | CPU → 中断控制器 | 允许中断,索要中断类型号 |
| 中断类型号 | 中断控制器/设备 → CPU,走数据线 | 告诉 CPU 是谁中断了 |
| EOI(中断结束) | CPU → 中断控制器 | 服务程序结束时通知控制器,外部设备不参与 |
最后一条最容易判反:EOI 是 CPU 发给中断控制器的,不是设备发出的。
中断优先级
多个设备同时请求中断时,按优先级排队。优先级通常的排列:
注意:DMA 请求不属于中断优先级体系,它通过总线仲裁机制处理(详见 DMA 章节)。硬件实现上,可通过中断屏蔽字设置每个中断源在被服务时屏蔽哪些中断。
多重中断(中断嵌套)
在处理一个中断的过程中,如果出现更高优先级的中断请求,CPU 可以暂停当前中断服务程序,转去处理更高优先级中断。
实现多重中断的条件:
- 中断服务程序中开中断(否则所有新中断都被屏蔽)
- 新中断的优先级高于当前正在处理的中断
中断屏蔽字的作用就是控制"哪些中断可以打断当前中断":
中断屏蔽字详解
中断屏蔽字用于调整中断的处理优先级。每个中断源在被服务时加载自己的屏蔽字,屏蔽字中某位为 1 表示屏蔽对应中断源(不允许打断),为 0 表示允许。
设置原则:
- 每个中断源至少屏蔽自身(防止同级中断重入)
- 处理优先级比自己低的中断源全部屏蔽
- 处理优先级比自己高的中断源允许通过(对应位为 0)
例 4:某机有 A、B、C、D 四个中断源,硬件响应优先级为
(1)写出每个中断源的中断屏蔽字。
动笔前的第 0 步:确认位序。本表按 左→右 = A B C D 排列。但真题常写成
这种左→右是降序的形式,两者方向相反。把位序在草稿纸上标出来再填表——把屏蔽字读反是这类题的主要失分方式。
| 中断源 | 处理优先级 | 需屏蔽 | 屏蔽字(A B C D) |
|---|---|---|---|
| A | 最高 | A、B、C、D | 1 1 1 1 |
| D | 第二 | B、C、D | 0 1 1 1 |
| C | 第三 | B、C | 0 1 1 0 |
| B | 最低 | B | 0 1 0 0 |
规律:屏蔽字中为 1 的位 = 自身 + 处理优先级比自己低的所有中断源。
(2)若 CPU 执行用户程序时 A、C、D 同时请求;随后在执行 C 的中断服务程序期间 B 请求。分析执行轨迹。
纵轴是嵌套深度——这才是多重中断的关键信息,画成一条直线会把"嵌套"看成"顺序执行":
嵌套深度
2 │ ┌──D──┐
│ │ │
1 │ ┌──A──┐ ┌──C───────┘ └──C──┐ ┌──B──┐
│ │ │ │ │ │ │
0 │──用户┘ └─用户──┘ └─用户─┘ └─用户──
└──────────────────────────────────────────────────────→ 时间看懂两处高低差:D 那一段压在 C 上面——C 并没有结束,它的现场还在栈里等着,这才叫嵌套;而 B 那一段回到了深度 1,说明它是 C 完全返回之后才开始的,与 C 无嵌套关系。
分析过程:
- A、C、D 同时请求,按响应优先级
,先响应 A - A 的屏蔽字 = 1111,所有中断被屏蔽,A 独占 CPU 直至完成
- A 完成后返回用户程序,C 和 D 仍然有效。按响应优先级先响应 C
- 进入 C 的服务程序,加载屏蔽字 0110。D 未被屏蔽(D 位 = 0),立即响应 D
- D 完成后返回 C,继续执行。此时 B 请求到达,但 C 的屏蔽字中 B 位 = 1,B 被屏蔽
- C 完成后返回用户程序,B 不再被屏蔽,CPU 响应 B
- B 完成后返回用户程序
交互可视化
例题
先分清两种查询模型——这决定用哪个公式
| 模型 | 题面怎么描述 | CPU 占比 |
|---|---|---|
| 独占查询(忙等) | "CPU 循环等待直到设备就绪""不做其他事" | 100%(定性结论,没什么可算的) |
| 定时查询 | "每隔 | 要算,见下式 |
408 的计算题一律是定时查询口径——因为只有它才有东西可算。看到题目给了"查询频率"或"查询间隔",就走下面的公式:
而每秒查询次数由设备决定:
编者注(方向别写反):查询间隔必须
设备准备一个数据的时间,否则数据还没被取走就被下一个覆盖。所以题目问的是"最多(最长)间隔多久查一次"、或者"至少多久查一次"——答"最少间隔"是要扣分的。
例 1:某 CPU 主频 500 MHz,每次查询 I/O 状态需要 50 个时钟周期。外设数据传输速率 100 KB/s,数据端口 8 位(每次传 1 B)。求 CPU 用于 I/O 查询的时间占比。
解:
编者注(单位口径):本文与真题解析统一取
、 (I/O 速率的惯例)。按 展开会得到 1.024%,与标答对不上。
例 1-b(改成 32 位端口):其余条件不变,数据端口 32 位(每次传 4 B)。
每次传几个字节由数据端口/缓冲寄存器的宽度决定,不是默认 1 字节——这一步错了整题就错了。
中断方式的占比怎么算
同一套骨架,只是把"查询"换成"中断":
单次中断周期数常常要自己折算——题目给的是指令条数:
例 1-c:主频 500 MHz,CPI = 5,外设 0.5 MB/s,数据端口 32 位。中断服务程序 18 条指令,其他开销折合 2 条指令。求 CPU 占比。
编者注(易错):两部分开销先相加再乘 CPI,别只乘服务程序那部分。
能不能用中断方式:一道判断题的固定算法
中断方式成立的物理前提:
违反了不是"性能差",而是物理上丢数据——上一个数据还没被搬走,设备已经把下一个覆盖上去了。
所以这类题的起手式是:算两个时间,比大小。
- 设备准备一个数据的时间
每次传输字节数 数据传输率 - 单次中断的总耗时(响应 + 服务程序)
- 前者
后者 → 可以用中断;否则必须用 DMA
答题时要写出"会丢数据"这个结论,只答"CPU 占用率太高"不到位。
例 2:中断响应过程中,哪些操作由硬件完成?哪些由软件完成?
解:硬件完成:关中断、保存断点(PC/PSW 入栈)、识别中断源、送入口地址到 PC。软件完成:保护现场(保存通用寄存器)、中断服务、恢复现场、中断返回。
例 3:设有 A、B、C 三个中断源,优先级 A > B > C。C 正在被服务时 A 和 B 同时请求,CPU 如何响应?
解:A 和 B 的优先级都高于 C,可以打断 C。因为 A > B,CPU 先暂停 C → 处理 A。A 完成后执行中断返回,恢复到 C 的断点并重新开中断。此时 B 的请求仍然有效且 B > C,CPU 立即响应 B → 处理 B → B 完成后返回继续 C。最终执行顺序:C(部分)→ A → B → C(完成)。
注意:A 处理完返回 C 后,CPU 一旦开中断就会立即检测到 B 的请求并响应,不会真正执行 C 的代码。具体处理顺序也可能因中断屏蔽字的设置而不同。
易混淆知识点
0. 断点和现场,谁保存、存哪里?
这是选择题最爱挖的坑,必须分清两组概念:
| 内容 | 谁来保存 | 存到哪 | |
|---|---|---|---|
| 断点 | PC(和 PSW) | 硬件(中断隐指令,进入 ISR 前自动完成) | 栈或指定单元 |
| 现场 | 通用寄存器等 ISR 会用到的寄存器 | 软件(ISR 开头的保护现场指令) | 栈 |
判断口径:凡是"不保存就再也找不回来的"(下一条指令地址)由硬件兜底;凡是"ISR 自己知道会破坏哪些"(通用寄存器)由软件按需保存。题目说"保存断点由中断服务程序完成"是错的——那是隐指令(硬件)的活。
1. 向量中断、中断向量、向量地址有什么区别?
- 中断向量:中断服务程序的入口地址
- 向量地址:中断向量在中断向量表中的存储位置(由中断类型号 × 表项长度计算得出)
- 向量中断:一种中断处理方式,由硬件自动提供中断类型号并查表定位服务程序入口
三者关系:向量中断方式下,CPU 获取中断类型号 → 计算向量地址 → 从向量地址处取出中断向量 → 转入中断服务程序。
2. 响应优先级和处理优先级一样吗?
不一定。响应优先级由硬件排队电路固定,决定多个请求同时到达时谁先被识别。处理优先级由中断屏蔽字动态控制,决定谁能打断谁。二者可以不同(如本文例 4)。
3. 程序中断和子程序调用有什么区别?
子程序调用由 CALL 指令主动发起,时机确定;中断由外部事件随机触发,具有异步性。子程序为主程序服务(主从关系);中断服务程序与主程序无关(平行关系)。子程序调用是纯软件行为,中断需要硬件支持(中断控制器、判优电路等)。
考点清单
- 程序查询方式 CPU 全程忙等,利用率最低
- 中断在每条指令执行结束时检测;异常在指令执行过程中检测
- 中断响应(硬件):关中断 → 保存断点 → 识别中断源 → 送入口地址
- 中断隐指令 = 关中断 + 保存断点 + 送入口地址(硬件自动,非真实指令;识别中断源是送入口地址的前置动作)
- 中断服务程序(软件):保护现场 → 中断服务 → 恢复现场 → 开中断 → 中断返回
- 占比 = 每秒次数 × 单次周期数 ÷ 主频;每秒次数 = 数据率 ÷ 每次传输字节数(由端口宽度定,不是默认 1B)
- 指令条数 × CPI 才是周期数;服务程序与其他开销先相加再乘
- 能否用中断:比
与 ,前者小则会丢数据,必须改 DMA - 向量中断(查表定位 ISR)vs 非向量中断(软件轮询定位 ISR)
- 中断向量 = 入口地址;向量地址 = 入口地址在向量表中的位置
- 中断向量表存放的是中断服务程序的入口地址,不是中断服务程序本身
- 多重中断需要两个条件:开中断 + 新中断优先级更高
- 中断屏蔽字控制当前中断服务期间可以被哪些中断打断
- 响应优先级(硬件固定)和处理优先级(屏蔽字调整)可以不同