中断系统这块内容在408组成原理里属于那种单独看好像都懂串起来做题就懵的典型章节。我当年复习到I/O方式这一块的时候程序中断方式看了不下五遍每次都觉得理解了一做题就发现漏洞百出——根源不在于中断方式本身难而在于前置知识没打牢。中断系统涉及硬件信号、CPU响应时机、优先级判优、屏蔽机制、向量地址生成这一整条链路任何一环模糊后面程序中断方式的流程就理不顺。这篇内容我打算把中断系统从头到尾拆一遍重点讲清楚每个机制为什么这么设计以及408考试里到底会怎么考。适合正在啃组成原理I/O章节的考研人也适合本科学这门课想搞懂底层逻辑的同学。1. 中断到底解决了一个什么问题1.1 从程序查询方式的死等说起要理解中断系统存在的意义得先看看没有中断的时候CPU是怎么干活的。程序查询方式下CPU要往外设传数据流程是这样的CPU发出启动命令然后进入一个循环不断读取外设的状态寄存器判断外设是否就绪。如果没就绪继续读就绪了传一个数据传完继续等下一个。这个模式的问题非常明显。假设外设是键盘人打字的速度和CPU执行指令的速度差了好几个数量级。CPU一个指令周期可能是纳秒级人按一次键是秒级。这意味着CPU99.99%的时间都在执行读取状态-判断-跳回这个无意义的循环。CPU被外设绑死了什么也干不了。你可以把这种模式想象成你去餐厅点餐点完之后你站在出餐口一直盯着厨师看厨师没做好你就不走也不干别的事。这显然是对你时间的巨大浪费。程序查询方式还有一个变种叫定时查询就是CPU每隔一段时间查一次不一直死等。但这又带来新问题查得太频繁浪费CPU时间查得太稀疏可能外设数据已经丢了比如键盘缓冲区溢出。这个间隔很难定一个通用值。1.2 中断的核心思想变主动等为被动通知中断的思路完全不同。CPU启动外设之后不等待直接去执行其他程序。外设完成一个数据单位的传输后主动发一个信号给CPU说我这边好了你来处理一下。CPU收到这个信号后暂停当前正在执行的程序转去执行一段专门处理这个外设请求的程序中断服务程序处理完再回到原来的程序继续执行。这个转变的本质是CPU从主动轮询变成了被动响应。外设变成了主动方CPU变成了响应方。CPU的时间利用率大幅提升因为它可以在外设工作的时候去执行其他任务。用餐厅的类比就是你点完餐拿一个震动取餐器然后回座位干自己的事。餐好了取餐器震动你再去取。你不需要一直盯着出餐口。这里有一个关键点需要理解中断方式下数据的传输本身仍然需要CPU参与CPU执行中断服务程序来完成数据搬运它不像DMA那样完全绕过CPU。中断方式节省的是等待时间不是传输时间。这是408选择题常考的一个区分点。1.3 中断方式与程序查询方式的定量对比408考试里有一类计算题比较程序查询和中断方式下CPU的效率。核心思路是这样的假设外设传输一个数据的时间是TCPU查询一次外设状态需要的时间是t。程序查询方式下CPU需要不断查询假设平均查询N次才能等到外设就绪那么CPU花在这个外设上的时间就是N×t。中断方式下CPU只需要执行中断服务程序的时间假设为t_service那么CPU花的时间就是t_service。效率提升的倍数大约是(N×t)/t_service。由于N通常很大外设慢这个倍数可以非常可观。但要注意中断方式并不是没有开销。中断响应本身需要时间保存断点、保存现场、跳转到中断服务程序、恢复现场、返回。这些开销加起来可能比传输一个数据本身还大。所以如果外设速度非常快中断方式反而不如查询方式。这也是为什么高速外设最终要用DMA的原因。考试里如果问中断方式是否一定比查询方式效率高答案是不一定要看外设速度和中断开销的相对关系。这个点在选择题里出现过。2. 中断系统的硬件基础从信号到响应2.1 中断源与中断请求信号的产生中断源就是能够发出中断请求的来源。常见的中断源包括外设键盘、鼠标、打印机等、定时器、硬件故障电源故障、存储器校验错、软件中断如系统调用等。每个中断源都有一个中断请求触发器也叫中断请求标志位当该中断源需要CPU服务时硬件将这个触发器置1。这个触发器通常位于外设接口电路中或者位于CPU内部的中断控制逻辑中。比如键盘接口电路中有一个数据就绪标志位当用户按下一个键键盘接口把数据放入数据寄存器同时把数据就绪标志位置1。这个标志位就是中断请求信号。这里要注意一个细节中断请求信号可以是电平信号也可以是边沿信号。电平信号是持续有效的只要条件满足就一直保持边沿信号是瞬间的只在状态变化的那一刻有效。CPU的中断请求输入端通常对电平敏感所以外设的中断请求信号需要保持到CPU响应为止。2.2 中断请求的锁存与排队多个中断源同时发出请求怎么办这就涉及到中断请求的锁存和排队。锁存的意思是中断请求信号必须被保存下来不能因为CPU暂时没响应就丢失。每个中断源对应一个触发器请求来了置1CPU响应后清0。这个触发器就是锁存的作用。排队的意思是多个请求同时到达时CPU需要决定先响应哪个。这就引出了中断优先级的概念。排队的硬件实现有两种典型方案第一种是链式排队器也叫菊花链。所有中断源串成一条链优先级高的靠近CPU。当多个请求同时到达时链上靠前的信号会阻断后面的信号从而实现优先级判优。这种方案的优点是结构简单缺点是优先级固定不灵活而且链上任何一个环节故障会影响后面的所有设备。第二种是并行排队器。每个中断源有独立的请求线和优先级编码电路通过优先级编码器选出当前最高优先级的请求。这种方案灵活可以通过编程改变优先级但硬件成本更高。408考试里链式排队器考得更多因为它的逻辑更直观容易出分析题。你需要理解链式排队器中如果高优先级的设备没有请求低优先级的请求才能传到CPU如果高优先级有请求它会截断后面的信号。2.3 CPU响应中断的条件与时机CPU并不是任何时候都能响应中断的。响应中断需要满足几个条件第一当前指令执行完毕。CPU在执行一条指令的过程中内部状态在不断变化此时响应中断会导致状态不一致。所以CPU只会在每条指令执行结束后检查是否有中断请求。这也是为什么中断响应的时间粒度是指令级的。第二没有更紧急的事件。比如CPU正在处理复位、正在执行DMA操作某些架构下DMA期间CPU不响应中断、或者当前处于关中断状态。第三中断没有被屏蔽。每个中断源可以被单独屏蔽通过中断屏蔽字如果该中断被屏蔽了即使有请求CPU也不会响应。关于响应时机有一个重要的概念叫中断响应周期。CPU在每条指令执行结束后会进入一个特定的机器周期中断响应周期在这个周期里完成检查中断请求、进行优先级判优、生成中断向量地址、保存断点。这个周期是CPU硬件自动完成的不需要软件干预。这里有一个容易混淆的点中断响应周期和中断服务程序是两回事。中断响应周期是硬件自动完成的非常短中断服务程序是软件由程序员编写可能很长。考试里问中断响应的时间通常指的是硬件响应周期的时间。3. 中断处理的完整流程拆解3.1 中断响应的硬件动作序列当CPU决定响应某个中断时硬件会自动完成以下动作以典型架构为例第一步关中断。CPU自动将中断允许触发器清零禁止新的中断请求进入。这一步的目的是防止在保存断点的过程中被新的中断打断导致断点丢失。第二步保存断点。将当前程序计数器PC的值保存到栈中或特定的保存寄存器中。断点就是被中断的程序的下一条指令的地址。保存断点是中断返回后能正确恢复执行的关键。第三步识别中断源并生成中断向量地址。CPU通过中断判优电路确定当前最高优先级的中断源然后根据中断源的类型号或编码生成对应的中断向量地址。中断向量地址指向中断服务程序的入口地址。第四步获取中断服务程序入口地址。根据中断向量地址从内存的中断向量表中读取中断服务程序的入口地址送入PC。第五步转去执行中断服务程序。此时CPU开始执行中断服务程序的第一条指令。注意以上五步中前三步是硬件自动完成的第四步可能涉及一次内存访问读中断向量表第五步开始就是软件执行了。3.2 中断服务程序的标准结构中断服务程序不是随便写一段代码就行它有固定的结构要求保护现场中断服务程序可能用到一些寄存器而这些寄存器在主程序中被使用着。如果不保护中断返回后主程序的状态就被破坏了。保护现场通常是把相关寄存器的值压入栈中。注意断点的保存是硬件自动完成的但其他寄存器通用寄存器、状态寄存器的保存需要软件完成。开中断在保护完现场之后通常要开中断允许更高级别的中断打断当前的中断服务程序。这就是中断嵌套的基础。如果不允许嵌套就不开中断。执行中断服务这是中断服务程序的核心部分根据中断源的不同执行不同的操作。比如键盘中断就是读取键盘数据寄存器的值存入缓冲区。关中断在恢复现场之前要再次关中断防止恢复过程中被新的中断打断。恢复现场把之前压栈的寄存器值弹出恢复主程序的执行环境。开中断并返回执行中断返回指令如IRET硬件自动从栈中弹出断点送入PC同时恢复中断允许状态。这个结构在408里经常以排序题的形式出现给你一堆操作让你排出正确的顺序。关键判断点是保护现场在开中断之前恢复现场在关中断之后中断返回是最后一步。3.3 中断嵌套与优先级处理中断嵌套是指CPU正在处理一个中断时又来了一个优先级更高的中断请求CPU暂停当前的中断服务程序转去处理更高优先级的中断处理完再回来继续。中断嵌套的实现依赖于两个机制优先级判优和中断屏蔽。优先级判优决定了新来的中断请求是否比当前正在处理的中断优先级更高。如果是才可能发生嵌套。中断屏蔽则允许程序员通过设置屏蔽字来动态调整哪些中断可以被响应。这里有一个经典的分析场景假设有A、B、C三个中断源优先级ABC。CPU正在处理B的中断服务程序此时A和C同时发出请求。问CPU会怎么处理答案是A的优先级高于B所以A可以打断B发生嵌套C的优先级低于B所以C被屏蔽或者说被挂起等B处理完再看C是否还有请求。如果B处理完后C的请求还在且此时没有更高优先级的请求CPU才会响应C。这个分析过程在408里经常考关键是要理清当前正在处理的中断优先级和新请求的优先级之间的关系。注意一个细节中断嵌套时每层嵌套都需要保存自己的断点和现场。所以栈会越来越深。如果嵌套层数太多可能导致栈溢出。这是实际系统设计中需要考虑的问题408里虽然不直接考但理解这一点有助于理解中断系统的开销。4. 中断向量与中断向量的生成方式4.1 中断向量的概念与作用中断向量是中断服务程序的入口地址。每个中断源对应一个中断向量。所有中断向量组成一个表叫中断向量表存放在内存的固定区域。中断向量表的作用是CPU响应中断时根据中断源的类型号查表得到中断服务程序的入口地址然后跳转过去执行。这样设计的好处是中断服务程序的位置可以灵活安排不需要固定在某个地址只需要在中断向量表里登记即可。中断向量表通常位于内存的低地址区域比如0x0000开始每个中断向量占4字节或8字节取决于地址宽度。中断源的类型号乘以每个向量的字节数就是该中断向量在表中的偏移地址。4.2 向量地址的形成过程向量地址的形成有两种典型方式方式一由中断源直接提供向量地址。某些架构中中断源在发出中断请求的同时通过数据总线提供一个向量号CPU直接用这个向量号作为索引去查中断向量表。这种方式速度快但需要中断源有额外的硬件支持。方式二由CPU的中断控制逻辑生成。CPU内部有一个中断类型号寄存器当识别到中断源后硬件自动将对应的类型号填入然后通过类型号×向量长度向量表基址计算出向量地址。这种方式更常见也更灵活。408考试里更常考的是方式二。你需要理解中断类型号是中断源的编号向量地址是中断向量在表中的位置中断向量是中断服务程序的入口地址。这三个概念容易混淆要分清楚。举个例子假设中断向量表基址是0x0000每个中断向量占4字节某中断源的类型号是9那么它的向量地址就是9×4360x0024。CPU从地址0x0024开始读取4个字节得到中断服务程序的入口地址。4.3 中断向量与中断服务程序入口地址的区别这是408选择题里反复出现的混淆点。我再强调一遍中断向量中断服务程序的入口地址是一个地址值。中断向量地址中断向量在中断向量表中的存储地址是存放中断向量的那个内存单元的地址。中断类型号中断源的编号用于计算中断向量地址。三者的关系是中断向量地址 中断向量表基址 中断类型号 × 每个向量的字节数中断向量 内存[中断向量地址]。考试里经常这样问中断向量地址是中断服务程序入口地址的地址这句话是对的。因为中断向量地址指向的内存单元里存放的是中断服务程序的入口地址。5. 中断屏蔽与优先级控制的硬件实现5.1 中断屏蔽字的作用机制中断屏蔽字是一个寄存器每一位对应一个中断源。某位为1表示屏蔽该中断源为0表示允许该中断源。CPU在响应中断前会检查屏蔽字如果对应位为1即使有请求也不响应。中断屏蔽字的核心作用是动态调整中断优先级。通过修改屏蔽字可以让某个中断源在处理期间屏蔽掉其他中断源从而实现处理期间不允许被打断的效果。这里有一个重要的应用场景假设有四个中断源A、B、C、D硬件优先级ABCD。如果CPU正在处理C按照硬件优先级A和B可以打断CD不能。但如果程序员希望C在处理期间不被任何中断打断可以把屏蔽字设置为屏蔽A、B、D即屏蔽字中对应A、B、D的位为1这样C的处理就不会被任何中断打断。反过来如果希望C能打断A的处理即让C的优先级在运行时高于A可以在A的中断服务程序中设置屏蔽字只屏蔽比A低的不屏蔽C。这样C的请求就能打断A。这就是通过屏蔽字改变优先级的原理。5.2 屏蔽字与优先级的配合关系在中断嵌套的场景中每一层中断服务程序都会设置自己的屏蔽字。屏蔽字的设置原则通常是屏蔽掉所有优先级不高于自己的中断源。这样保证只有更高优先级的中断才能打断当前处理。具体来说如果当前处理的是优先级为i的中断那么屏蔽字应该屏蔽所有优先级≤i的中断源。这样优先级i的中断源仍然可以发出请求并被打断实现嵌套。这个规则在408的分析题里经常用到。题目会给出多个中断源的硬件优先级和处理时间让你画出CPU执行这些中断服务程序的时间轴。解题的关键就是根据屏蔽字判断哪些中断可以嵌套哪些必须等待。5.3 多重中断的完整分析案例我拿一个典型的408题目场景来演示分析过程假设有A、B、C三个中断源硬件优先级ABC。A的处理时间是20个时钟周期B是10个C是5个。在时刻0A和B同时发出请求在时刻5C发出请求。分析过程时刻0A和B同时请求。A优先级高CPU先响应A。响应A时硬件自动关中断然后A的中断服务程序开始执行。A的服务程序会设置屏蔽字屏蔽B和C因为B和C的优先级都低于A。时刻5C发出请求。但此时A正在处理且C被A的屏蔽字屏蔽了所以C的请求被挂起CPU不响应。时刻20A处理完毕。恢复现场开中断返回主程序。此时B和C的请求都还在。B的优先级高于C所以CPU响应B。时刻20到时刻30B在处理。B的服务程序设置屏蔽字屏蔽CC优先级低于B。C继续等待。时刻30B处理完毕。CPU响应C。时刻30到时刻35C在处理。最终时间轴A从0到20B从20到30C从30到35。如果题目改成在时刻5C发出请求且C的优先级高于A通过屏蔽字动态调整那么C可以在时刻5打断AA的处理被暂停C先处理完时刻5到10然后A继续时刻10到30。这就是动态优先级的效果。这类题目在408里几乎每年都出现核心就是搞清楚屏蔽字的作用和嵌套的条件。建议多画时间轴把每个时刻的状态标清楚。6. 程序中断方式下的数据传送全过程6.1 从外设就绪到数据落入内存的完整链路现在把中断系统的知识和程序中断方式的数据传送串起来。假设我们要从键盘读入一个字符到内存缓冲区完整流程如下阶段一CPU启动外设。CPU执行一条输出指令向键盘接口发送启动命令实际上键盘不需要启动这里以更通用的外设为例。CPU继续执行后续程序不等待。阶段二外设准备数据。外设开始工作准备一个数据单位。对于输入设备就是把数据准备好放入数据寄存器。阶段三外设发出中断请求。外设准备好数据后将接口电路中的中断请求触发器置1向CPU发出中断请求信号。阶段四CPU响应中断。CPU在当前指令执行结束后检查到中断请求且满足响应条件未被屏蔽、优先级足够等进入中断响应周期。硬件自动关中断、保存断点、生成向量地址、获取中断服务程序入口地址。阶段五执行中断服务程序。中断服务程序首先保护现场然后开中断允许嵌套接着执行核心操作从外设的数据寄存器读取数据存入内存缓冲区。然后修改缓冲区指针判断是否传输完成。最后关中断、恢复现场、开中断、返回。阶段六中断返回。执行中断返回指令硬件从栈中弹出断点送入PC恢复中断允许状态CPU回到主程序继续执行。这个流程里CPU实际参与数据传送的时间只有阶段五中读取数据寄存器那一条指令的时间其余时间CPU都在执行主程序。这就是中断方式高效的原因。6.2 中断方式与DMA方式的本质区别408里经常把中断方式和DMA方式放在一起比较。核心区别在于对比维度程序中断方式DMA方式数据传送的控制者CPU执行中断服务程序DMA控制器CPU参与程度每个数据单位都需要CPU执行指令只在传送开始和结束时需要CPU中断的作用请求CPU传送数据通知CPU传送结束适用场景低速、少量数据高速、大批量数据优先级通常低于DMA通常高于中断关键理解中断方式下中断请求是请求CPU来传数据DMA方式下DMA请求是请求占用总线传送结束后才用中断通知CPU。两者中断的含义不同。6.3 中断方式的实际开销分析中断方式虽然比查询方式高效但开销也不小。一次完整的中断处理开销包括中断响应周期硬件保存断点、生成向量地址约几个时钟周期。保护现场压栈操作取决于需要保护的寄存器数量可能十几到几十个时钟周期。中断服务程序核心逻辑读取数据、存内存、修改指针、判断结束约几个到十几个时钟周期。恢复现场出栈操作与保护现场相当。中断返回硬件恢复断点几个时钟周期。总计可能几十到上百个时钟周期。如果外设传输一个数据的时间只有几个时钟周期高速外设那么中断开销就太大了。这就是为什么高速外设要用DMA。408里有一类计算题给定外设传输速率和中断开销问中断方式下CPU用于该外设的时间占比。解题思路是算出每秒的中断次数乘以每次中断的开销时间再除以1秒。实际做题时要注意单位换算。外设速率通常给的是KB/s或MB/s中断开销给的是时钟周期数需要知道CPU主频才能换算成时间。这类题目计算量不大但容易在单位上出错。7. 408真题里中断系统的常见考法与避坑7.1 中断响应时机的选择题陷阱408选择题里关于中断响应时机有几个经典陷阱陷阱一中断响应发生在指令执行过程中。这是错的。CPU只在每条指令执行结束后检查中断请求。如果一条指令执行时间很长比如除法指令中断响应会被推迟到该指令结束。陷阱二中断响应发生在总线周期结束后。这个说法在某些架构下是对的但在408的典型模型中中断响应是在指令结束后。要注意题目问的是哪种架构。陷阱三中断响应后立即执行中断服务程序。不完全对。中断响应后硬件先完成保存断点、获取向量地址等动作然后才跳转到中断服务程序。中间有一个过渡过程。7.2 中断向量相关计算的易错点中断向量的计算题易错点主要有易错点一混淆中断类型号和中断向量地址。题目给中断类型号问中断向量地址需要用类型号乘以向量长度再加上基址。如果直接拿类型号当地址就错了。易错点二忘记向量长度的单位。向量长度通常以字节为单位但地址计算时要注意是字节地址还是字地址。如果题目说按字编址计算方式不同。易错点三中断向量表基址的默认值。有些题目不明确给出基址默认从0开始。但有些题目会给出特定的基址要仔细读题。我个人的经验是做这类题时先把三个概念写在草稿纸上——类型号、向量地址、向量内容然后一步步代入不要跳步。7.3 多重中断时间轴题目的解题套路多重中断的时间轴题目我总结了一个固定的解题流程第一步列出所有中断源的硬件优先级。通常题目会给出或者通过屏蔽字推断。第二步确定每个中断源的服务程序执行时间和屏蔽字。屏蔽字决定了哪些中断可以嵌套。第三步按时间顺序模拟。从时刻0开始遇到中断请求就判断当前是否有更高优先级的中断正在处理如果没有响应如果有等待。第四步画出时间轴。每个中断源占一行标出开始和结束时刻。第五步检查嵌套关系。确认每个时刻CPU在执行哪个中断服务程序是否符合屏蔽字规则。这个流程看起来简单但实际操作时容易在等待的中断何时被响应这个点上出错。关键原则是等待的中断在当前中断服务程序结束后如果没有被屏蔽且优先级足够就会被响应。如果有多个等待的中断选优先级最高的。我踩过的一个坑有一次做题时忽略了中断服务程序执行完毕后会开中断这个动作导致误以为等待的中断要等到所有嵌套都结束才响应。实际上每层中断服务程序结束时都会开中断此时如果有等待的更高优先级中断会立即响应。这个细节在复杂嵌套场景下很容易搞错。7.4 中断屏蔽字设置的实战技巧屏蔽字的题目通常有两种问法问法一给定屏蔽字问哪些中断可以被响应。解题方法把屏蔽字和中断请求字做逻辑与或逻辑或取决于定义看结果。问法二给定需求问屏蔽字应该怎么设置。解题方法根据屏蔽所有优先级不高于当前中断的中断源这个原则确定每一位的值。这里有一个容易混淆的点屏蔽字的位定义。有些教材定义1表示屏蔽有些定义0表示屏蔽。408考试里通常采用1表示屏蔽的定义但做题时一定要看清楚题目说明。如果搞反了整道题就废了。另外屏蔽字通常是每个中断源一个而不是全局一个。也就是说A的中断服务程序有自己的屏蔽字B的有自己的。这样设计是为了让不同中断源可以根据自己的需求灵活控制嵌套关系。8. 中断系统与其他I/O控制方式的衔接8.1 为什么中断方式不是终点中断方式解决了CPU等待的问题但没解决CPU参与数据传输的问题。每个数据单位的传输仍然需要CPU执行指令来完成。对于高速外设如磁盘、网卡数据到达的速度非常快如果每个数据都中断一次CPU会被中断淹没根本来不及处理其他任务。这就是DMA方式出现的背景。DMA控制器可以在不需要CPU干预的情况下直接在内存和外设之间传送数据块。CPU只需要在传送开始前初始化DMA控制器在传送结束后处理一次中断即可。从查询到中断到DMA本质上是一个CPU参与度逐渐降低的过程查询方式CPU全程参与等待传输。中断方式CPU不等待但参与每个数据的传输。DMA方式CPU既不等待也不参与数据传输只参与初始化和结束处理。理解这个演进逻辑对于理解整个I/O章节的体系结构非常重要。408考试里经常出综合题把几种方式放在一起比较。8.2 中断方式在通道和I/O处理机中的角色在更大规模的系统中还有通道和I/O处理机。通道是一个专门负责I/O控制的处理器它可以执行通道程序控制多台外设的数据传送。I/O处理机则更强大几乎是一个独立的计算机。在这些系统中中断仍然存在但角色变了。通道完成一批数据传输后向CPU发中断通知CPU处理。此时中断的粒度更粗频率更低CPU的负担更小。408考试对通道和I/O处理机的考查相对较少主要考概念和比较。但理解它们在I/O体系中的位置有助于建立完整的知识框架。8.3 中断方式在 modern 系统中的体现虽然408考的是经典模型但中断的思想在现代系统中无处不在。比如操作系统的系统调用本质上就是通过软中断或陷阱指令从用户态切换到内核态。再比如网络数据包的到达网卡通过中断通知CPU处理。现代系统为了减少中断开销还发展出了中断合并、轮询混合等技术。但这些已经超出408的考查范围了解即可。回到408的备考我的建议是把中断系统当作一个完整的硬件-软件协同机制来理解不要孤立地背概念。每个机制都有它要解决的问题理解了问题机制就自然记住了。最后分享一个我复习时用的方法拿一张白纸从外设发出中断请求开始一步步画出到CPU返回主程序的完整流程每一步标注是硬件还是软件完成的。画三遍中断系统的脉络就彻底清晰了。这个方法比反复看书有效得多因为画图的过程强迫你理清每个环节的因果关系而不是被动地记忆。
