8259A:掌握中断大权的傲娇女王!👑

![[5fc6160c5f7c8 1.pdf]]

1.0 中断处理基础:一个五步协议

中断处理并非一系列孤立的事件,而是一个基础协议,用于管理异步硬件事件与同步CPU执行之间的交互。该协议确保了CPU能够高效地处理外部请求,同时维持主程序的完整性。整个过程可分解为五个逻辑连贯的阶段。

1.1 步骤一:中断请求 (Interrupt Request)

中断处理的起点是中断源发出的服务请求。中断源可分为内部中断源和外部中断源两大类 1。内部中断源于程序执行过程本身,是同步于程序计数器的事件,例如执行

INT n指令、发生除零错误或运算溢出 1。外部中断源则由外部硬件设备触发,通过CPU的特定引脚(如NMI或INTR)发出异步信号,其发生时间相对于CPU的指令流是不可预测的 1。

这一步骤的本质是建立了一种“异步契约”。外部设备在需要服务时发出信号,无需关心CPU当前正在执行何种任务。相应地,CPU承诺在满足特定条件时最终会响应此请求。这种解耦的通信机制是现代计算中实现高效I/O和多任务处理的基石。与此相对的是轮询(Polling)机制,CPU需要不断地查询设备状态,这会极大地浪费处理器资源。中断机制则允许CPU在等待I/O操作完成时继续执行其他有用的计算任务,从而显著提升了系统的并行处理能力 1。

1.2 步骤二:中断仲裁与优先级判定 (Interrupt Arbitration and Prioritization)

在现实世界的应用中,多个中断请求可能同时到达。为了确保系统的稳定性和实时性,必须建立一个仲裁机制来决定首先响应哪个请求,这就是中断优先级判定 1。若无优先级管理,一个关键且时效性强的事件(如通过NMI引脚传入的电源故障警告)可能会被一个常规事件(如通过INTR引脚传入的键盘输入)所延迟,从而导致系统崩溃。

8086体系结构在此展现了明确的职责划分。CPU自身负责宏观层面的优先级管理,即在其核心中断类型之间进行裁决。其固有的、不可编程的优先级顺序为:内部中断(如除法错误、INT n指令)> NMI中断 > INTR中断 > 单步中断 1。然而,8086 CPU只有一个可屏蔽中断请求引脚(INTR),无法直接处理来自多个外部设备的请求 1。因此,它将微观层面的优先级管理——即在多个可屏蔽硬件设备之间进行仲裁——的职责委托给了一个专门的外围芯片,即可编程中断控制器8259A 1。这种设计将复杂的优先级判定逻辑从CPU核心中剥离,转移到一个可编程的专用模块上,不仅简化了CPU的设计,也使得整个中断系统更具模块化和可扩展性。8259A的存在正是为了解决由单一INTR引脚所带来的扇入、优先级排序和中断向量提供等一系列问题 1。

1.3 步骤三:中断响应 (Interrupt Response)

CPU并不会在收到中断请求后立即处理,而是需要满足一系列响应条件。对于可屏蔽中断(INTR),要求当前指令执行完毕、CPU处于开中断状态(即中断允许标志位$IF=1$),且无更高优先级的中断请求(如NMI)等待处理 1。一旦条件满足,CPU便进入中断响应周期,由其内部微码自动执行一系列硬件操作。

此过程的核心是保存当前程序的执行上下文,以确保中断服务完成后能准确返回。CPU硬件自动完成以下操作:

  1. 将程序状态字(PSW,即标志寄存器)压入堆栈。

  2. 将当前代码段寄存器(CS)的内容压入堆栈。

  3. 将指令指针(IP)的内容压入堆栈 1。

    这三者共同构成了被中断程序的“断点”(Breakpoint),即下一条将要执行的指令地址及其执行时的处理器状态 1。

随后,CPU会自动清除中断允许标志位(IF)和陷阱标志位(TF)1。最后,CPU通过特定方式(对于INTR,需要从外部控制器获取)获得中断类型号,并以此为索引在中断向量表中查找中断服务程序的入口地址 1。

CPU硬件的设计体现了“最小必要状态保存”的优化原则。它仅保存了恢复程序执行所必需的绝对最小状态(PSW、CS、IP),而并未保存通用寄存器(如AX、BX等)。这是因为并非所有中断服务程序都会使用到全部通用寄存器,强制保存所有寄存器会给简短的服务程序带来不必要的性能开销。将这部分工作留给软件开发者,可以根据具体情境决定需要保存哪些寄存器,从而实现更高的效率 1。同时,自动清除IF标志位的行为至关重要,它使CPU进入一个临时的“安全模式”,防止新的可屏蔽中断在当前中断服务程序尚未完成初始化时就将其打断,从而避免了潜在的竞态条件和堆栈错误。

1.4 步骤四:中断服务 (Interrupt Servicing)

在获取中断服务程序(Interrupt Service Routine, ISR)的入口地址后,CPU跳转至该地址开始执行。这是中断处理的“有效载荷”阶段,即执行具体任务以响应该中断事件 1。

一个设计良好的ISR通常遵循固定的结构。在其起始部分(prologue),程序会首先保存所有即将被修改的通用寄存器的内容(通常通过PUSH指令压入堆栈),这被称为“保护现场” 1。随后,执行处理中断事件的核心代码。在程序的结束部分(epilogue),通过

POP指令从堆栈中恢复之前保存的通用寄存器,称为“恢复现场” 1。这种设计确保了ISR的执行对于被中断的主程序是完全透明的,即主程序在恢复执行时,其所有寄存器状态与被中断前完全一致。

在ISR执行期间,由于IF标志位已被硬件自动清零,默认情况下它不会被其他可屏蔽中断再次打断。然而,为了构建响应更及时的实时系统,有时需要允许更高优先级的中断来打断当前正在执行的低优先级ISR,这即是“中断嵌套”(Interrupt Nesting)1。为实现嵌套,ISR必须在完成现场保护和必要的初始化后,通过执行

STI(Set Interrupt Flag)指令显式地重新开中断 1。这是一个关键的编程决策,它虽然增加了程序的复杂性,但可以防止一个耗时较长的低优先级服务阻塞一个紧急的高优先级请求。

1.5 步骤五:中断返回 (Interrupt Return)

中断服务程序的最后一步是执行一条特殊的中断返回指令IRET 1。这条指令的功能是将在中断响应阶段压入堆栈的上下文信息恢复到对应的寄存器中,从而使CPU返回到被中断的程序继续执行。

IRET指令与常规的子程序返回指令RET有本质区别。IRET指令以原子的方式执行三个连续的出栈操作:首先将堆栈顶的值弹出到指令指针(IP),然后是代码段寄存器(CS),最后是程序状态字(PSW)1。恢复顺序至关重要,特别是将标志寄存器安排在最后恢复。因为保存在堆栈中的PSW值包含了中断发生

_之前_的IF标志位状态。通过在最后一步恢复PSW,IRET指令能够自动地将系统的可中断状态恢复到中断前的原样。整个操作的原子性确保了在CS和IP被恢复之后、PSW被恢复之前,不会有任何新的中断插入,从而杜绝了可能导致堆栈损坏或上下文丢失的风险。

2.0 Intel 8086微处理器中断系统

Intel 8086的中断系统是其体系结构的核心组成部分,它定义了处理器如何识别、分类和响应来自软件和硬件的各种中断事件。

2.1 8086中断源的分类

8086的中断源可以根据其触发方式分为内部中断和外部中断 1。

2.1.1 内部(软件)中断

内部中断由CPU内部事件或特定指令的执行而触发,其发生是同步且可预测的 1。主要包括以下几种类型:

2.1.2 外部(硬件)中断

外部中断由CPU外部的硬件设备通过处理器的物理引脚发起,其发生是异步的,可能在任何指令执行的间隙出现 1。8086提供了两个用于接收外部中断的引脚:NMI和INTR 1。

2.2 NMI与INTR的比较分析

NMI(Non-Maskable Interrupt,非可屏蔽中断)和INTR(Interrupt Request,可屏蔽中断请求)为外部设备提供了两种性质截然不同的中断通道,体现了系统设计的核心哲学:为紧急事件提供保障通道,为常规I/O提供灵活通道。

2.3 8086中断优先级体系

8086处理器内部实现了一套固定的、不可编程的优先级仲裁机制,以处理不同来源中断的冲突。这个固定的优先级顺序揭示了其架构设计的内在逻辑和对事件重要性的评估 1。

优先级从高到低的顺序是:

  1. 内部中断(除法错误、INT nINTO

  2. NMI(非可屏蔽中断)

  3. INTR(可屏蔽中断)

  4. 单步中断

这个排序的背后逻辑如下:

2.4 中断向量表 (Interrupt Vector Table, IVT)

为了将中断类型号与对应的中断服务程序(ISR)地址关联起来,8086采用了一个名为中断向量表的软件结构。IVT是8086中断系统实现间接寻址的核心机制,它将中断源的标识(类型号)与服务程序的物理位置解耦,提供了极大的灵活性 1。

下表总结了8086主要中断类型的特性:

表 2.1:8086中断类型特性对比

特性 内部中断 (异常, INT n) NMI (非可屏蔽中断) INTR (可屏蔽中断)
触发机制 指令执行(如INT n、除法错) 外部引脚NMI的上升沿 外部引脚INTR的高电平
同步性 同步于指令流 异步于指令流 异步于指令流
可屏蔽性 不可屏蔽 不可屏蔽 可屏蔽
控制标志 中断允许标志 (IF)
关联引脚 NMI INTR
向量获取 由指令或CPU硬件直接提供 由CPU硬件固定为类型2 由外部控制器在INTA周期提供
典型用途 系统调用、软件调试、异常处理 紧急硬件故障(电源、内存错误) 常规外部设备I/O(键盘、磁盘)

3.0 Intel 8259A可编程中断控制器 (PIC)

Intel 8259A是一款功能强大的外围芯片,旨在扩展和增强基于Intel微处理器的中断系统。它作为8086 CPU的INTR输入的智能前端,解决了单个INTR引脚无法管理多个中断源的根本问题 1。

3.1 核心功能与系统集成

8259A的核心使命是作为一个中断的管理者和仲裁者,其主要功能包括 1:

3.2 内部架构:关键寄存器深度剖析

8259A的强大功能源于其内部精巧的寄存器设计。其中三个8位寄存器——中断请求寄存器(IRR)、服务中寄存器(ISR)和中断屏蔽寄存器(IMR)——协同工作,构成了一个完整的中断处理状态机 1。

3.2.1 中断请求寄存器 (Interrupt Request Register, IRR)

IRR用于锁存来自外部设备的中断请求。当IRi引脚上出现有效的中断请求信号时,IRR中对应的第i位将被置为1,表示有一个待处理的中断请求 1。这个寄存器的内容可以被CPU读取,以查询当前有哪些中断源正在请求服务。

3.2.2 服务中寄存器 (In-Service Register, ISR)

ISR用于跟踪当前正在被CPU服务的,或者因被更高优先级中断打断而暂停服务的中断。当CPU响应一个中断请求(例如来自IRi)后,8259A会自动将ISR中对应的第i位置为1,同时清除IRR中的相应位。该位置1的状态将一直保持,直到CPU的中断服务程序向8259A发送一个中断结束(End of Interrupt, EOI)命令为止 1。ISR的存在是实现中断嵌套的关键,因为优先级判优器会参考ISR的状态,只允许优先级高于ISR中当前最高有效位的中断请求通过。

3.2.3 中断屏蔽寄存器 (Interrupt Mask Register, IMR)

IMR允许程序员通过软件来选择性地屏蔽或允许各个中断源。IMR是一个8位读/写寄存器,若其第i位被置为1,则来自IRi引脚的中断请求将被忽略,无法触发向CPU的INT信号。若为0,则该中断请求被允许。通过写IMR,可以动态地调整系统的中断响应能力 1。

3.2.4 优先级判优器 (Priority Resolver) 与控制逻辑

优先级判优器是8259A的大脑。它持续监视IRR的内容,并结合IMR的屏蔽状态,确定所有未被屏蔽的待处理请求。然后,它将这些请求的优先级与ISR中正在服务的最高优先级中断进行比较。只有当一个待处理请求的优先级高于所有正在服务的请求时,判优器才会指示控制逻辑向CPU发出INT信号 1。控制逻辑则负责处理与CPU之间的握手信号(

INTINTA),并解释来自CPU的初始化命令字(ICWs)和操作命令字(OCWs)以配置8259A的工作模式 1。

这三个寄存器共同构成了一个严密的状态机:

  1. 请求到达: 外部设备在IR线上发信号,IRR的对应位置1(状态:“请求待决”)。

  2. 权限过滤: 优先级判优器检查该位在IMR中是否为0(“权限过滤器”)。

  3. 优先级比较: 若未被屏蔽,判优器将此请求的优先级与ISR中当前置位的最高优先级进行比较(状态:“正在服务”)。

  4. 发起中断: 如果新请求的优先级更高,8259A通过INT引脚向CPU请求中断。

  5. 状态转换: CPU响应INTA后,8259A将该中断的标志位从IRR中清除,并在ISR中置位(状态转换:“待决” -> “服务中”)。

这个精巧的流程确保了中断处理的有序性和可嵌套性。

表 3.1:8259A内部核心寄存器功能描述

寄存器 全称 目的 位如何置位 位如何清除
IRR 中断请求寄存器 锁存外部设备的中断请求信号 由外部IR引脚的有效信号触发 当CPU响应中断时,由8259A内部逻辑清除
ISR 服务中寄存器 记录正在被CPU服务的中断 当CPU响应中断时,由8259A内部逻辑置位 由CPU软件发送EOI(中断结束)命令
IMR 中断屏蔽寄存器 允许/禁止特定的中断请求 由CPU软件通过写操作置位(屏蔽) 由CPU软件通过写操作清除(允许)

3.3 8259A的完整操作流程

从接收请求到服务结束,8259A与CPU的交互遵循一个精确定义的时序 1:

  1. 请求锁存: 一个或多个外部设备在IR0-IR7引脚上产生高电平请求,IRR的相应位置1 1。

  2. 屏蔽与判优: 优先级判优器检查IRR,忽略被IMR屏蔽的位,并在剩余的请求中确定优先级最高的那个。

  3. 发出INT: 如果该最高优先级请求的级别高于ISR中任何正在服务的级别,控制逻辑将INT引脚置为高电平,向CPU发出中断请求 1。

  4. CPU响应(第一次INTA): CPU在当前指令结束后,若IF为1,则响应中断。它会执行第一个中断响应总线周期,并发出第一个低电平有效的INTA脉冲 1。

  5. 内部状态更新: 收到第一个INTA脉冲后,8259A的内部逻辑被“锁定”。它将最高优先级请求对应的位从IRR中清除,并在ISR中置位 1。

  6. CPU响应(第二次INTA): CPU紧接着执行第二个中断响应总线周期,并发出第二个INTA脉冲 1。

  7. 向量发送: 在第二个INTA脉冲有效期间,8259A将预先编程好的、与该中断源对应的8位中断类型号放置到数据总线D0-D7上 1。

  8. CPU获取向量并跳转: CPU从数据总线上读取中断类型号,中断响应周期结束。随后,CPU使用该类型号在IVT中查找ISR地址并跳转执行。

  9. 中断结束(EOI): 中断服务程序在执行完毕、返回主程序(通过IRET)之前,必须向8259A发送一个EOI命令。该命令会清除ISR中相应的位,标志着此次中断服务彻底完成,从而允许同级或更低优先级的中断被响应 1。

其中,两次INTA脉冲的握手协议设计得非常巧妙。第一个INTA脉冲的作用是“提交”或“锁定”信号,它通知8259A:“中断已被接受,请立即冻结你当前的优先级判优结果。” 这可以防止在CPU响应和获取向量之间到达的更高优先级请求“劫持”本次中断响应周期。第二个INTA脉冲则是“输出使能”信号,通知8259A:“数据总线已准备好,请将已锁定的中断向量放上来。” 这个两阶段过程确保了CPU最终获取的向量始终对应于最初被响应的那个中断请求,保证了系统的稳定性和确定性。