Contents

8086 中断笔记

中断机制

何为中断?中断是一种打断处理器当前运行流程进而获得其控制权的机制。可以说如果没有中断这种机制,那么处理器就是个只会朝着某个方向一直冲的铁憨憨,别人叫它,它也不一定能正确地理会,哪怕键盘敲烂了都没有。每个中断都对应一个编号,处理器处理中断时,根据编号找到它对应的中断处理程序的入口地址,拿到中断处理程序地址后,将之前程序的上下文(CS, IP, FLAGS)入栈保存并将 IF 和 TF 清零,然后跳转到中断处理程序入口处执行。中断处理程序执行完毕后调用 iret 指令(作用就是将之前保存的上下文再按正确顺序出站)返回之前的程序继续执行。处理器响应中断跳到其对应的中断处理程序执行的过程即控制权从原来的程序转移到新程序的过程。与一般的子程序一样,中断处理程序内部要要用到的寄存器在使用之前应该将它们的数据保存入栈,在返回之前再恢复原状,以免破坏外部程序的状态。

中断分类

处理器提供两种途径触发中断,一种是从处理器外部通过向一个叫做 8259A 的可编程中断控制器发送信号来产生中断,另一种是处理器内部自行产生中断(由程序直接调用中断指令,或是某些条件下处理器执行指令时自己产生),前者产生的叫外中断,后者叫内中断。外中断又分为可屏蔽中断和不可屏蔽中断。

外部中断

可屏蔽中断的信号通过 INTR 信号线传递,最终被处理器处理需要经过两道关卡,第一个是 8259A,8259A 可以控制是否为从外部收到的中断信号生成对应的中断通知给处理器,外部硬件产生的中断信号只有被 8259A 生成对应的中断通知给处理器才有可能被处理器处理;过了 8259A 那关才能进到第二关:处理器中标志寄存器的 IF 位的值。如果是处理器从 8259A 那里收到中断事件时,当前的 IF 位为 0,那么这个中断也不会被处理,只有 IF 位为 1 才会被处理。

不可屏蔽中断的信号则通过 NMI 信号线传递。顾名思义,与可屏蔽中断相比,不可屏蔽中断产生时,处理器必须处理。正因如此,不可屏蔽中断通常意味着一些灾难性事件,比如即将断电、内存检测异常、总线校验错误等。显然它的优先级也比可屏蔽终端要高(当同时有多个中断产生时)。NMI 中断编号为 2。

内部中断

内部中断分为通过 INT 指令产生的中断(称为 software interrupt)和处理器自己产生的中断。前者除了 INT 指令外,还有断点中断指令 INT3 (中断编号为 3)和溢出中断指令 INTO(中断编号为 4)。后者则包括处理器做除法运算时除数为零时产生的除数为零中断(中断编号为 0)、处理器执行完一条指令发现 TF 标记位为 1 时产生的单步调试中断(中断编号为 1)。

常见中断优先级

中断优先级由高到低:

  • 除数为 0、INT n、INTO
  • NMI
  • INTR
  • 单步调试中断

中断向量表

8086 处理器可以支持 256 种中断,从 0 编号到 255。每个编号对应一个中断处理程序的入口地址,这个入口地址为一个偏移地址和段地址组成的二元组,这个二元组就是中断向量,256 个二元组组成的表也就是中断向量表。这个表从 0 号中断向量开始依次存储在 0x00000~0x003ff 对应的 1KB 内存空间,每个中断向量占 4 个字节,低地址 2 个字节存储偏移地址,高地址 2 个字节存储段地址。也就是说对于 256 个中断中的某个 n 号中断,其对应的中断向量为 (4*n, 4*n+2)。