汇编语言 第12章 内中断

隐藏

内部中断的产生

当8086 CPU内部发生下面情况时,将产生相应中断信息。

  1. 除法错误,比如,执行div产生除法溢出
  2. 单步执行
  3. 执行into指令
  4. 执行int指令

以上不同的中断信息,CPU要作不同的处理, 因此,CPU首先要知道中断信息来源,那么中断信息就必须包含识别来源的编码。 8086 CPU用称为中断类型码的数据来标识中断信息的来源。

中断信息码为一个byte,可表示256种中断信息。 上述中断的相关中断码为:

  1. 除法错误:0
  2. 单步执行:1
  3. into指令:4
  4. int n 指令(n为byte型立即数):n

int即 interrupt,中断。 into应该是 interrupt out的简称, 之所以只需要一个数字4,猜测应该是统一跳转到外部程序,由外部程序处理, 这样只需外部程序考虑不同处理方式。

中断处理程序

CPU收到中断信息后,需要处理中断,我们可以自己编写相关中断程序。

首要问题是,收到中断信息后,如何根据中断信息,确定处理程序的入口。 因此,CPU设计者需要在中断信息和对应处理中断程序之间建立某种联系。

中断类型码的作用就是定位中断处理程序。 那么就要在字码和中断处理地址之间建立关系, 一个数组就可以搞定,没错,8086中就是存放256个中断处理程序地址的中断向量表

中断向量表

对于8086 CPU,中断向量表存放在0000:0000到0000:03FF这1024个单元中, 对于256个中断地址,正好一个中断地址对应4个byte,CS和IP各占2byte。

中断过程

中断过程由CPU硬件实现,CPU收到中断信息后,首先引发中断过程。 硬件完成中断过程后,CS:IP将指向中断处理程序入口,CPU开始执行中断程序。

有一个问题需要考虑,CPU执行完中断后,应该返回原来执行的位置。 所以,中断过程中,在设置CS:IP之前,需要先将原CS:IP保存起来。

因此,完整的中断过程如下:

  1. 取得中断类型码
  2. 标志寄存器的值入栈(因中断会改变标志寄存器原来的值)
  3. 设置标志寄存器的TF和IF的值为0
  4. CS内容入栈
  5. IP内容入栈
  6. 将内存中[中断码4]和[中断码4+2]两个字单元的数据设置到IP和CS中。
  7. 执行中断程序

中断处理程序和iret指令

iret(interrupt return)用于中断程序的返回,相当于: pop IP pop CS popf

单步中断

如上所述,中断是会设置标志位TF和IF = 0, 而如果检测到标志位TF = 1(Test Flag),则产生单步中断。 CPU提供单步中断功能就是为单步跟踪程序的执行过程提供实现机制。

具体而言, 首先单补执行的中断码为1,所以要设置单步中断指令, 就要将其中断码设置为1, 设置之后,为了让程序单步执行(即每执行完一步后,立即执行中断码为1的程序) 但不可能每个代码都插入一个int 1吧,所以用一个标志寄存器TF = 1(Test Flag)来解决这个问题。

总的而言,设置单步中断分两步:

  1. 设置中断码为1的中断指令(例如可以显示寄存器值、或者某个参数值之类的)
  2. 单步执行处设置TF = 1,退出单步执行时设置TF = 0

响应中断的特殊情况

有些情况下,检测到中断后不能马上中断,例如:

mov ax, 1000h
mov ss, ax
mov sp, 0

在执行mov ss, ax过程中,如果发生中断,sp这时还没有设置正确的值, 那么如果发生中断,则栈指针将指向错误的内存地址。

而且执行mov ss, ax后,应该马上执行mov sp, 0操作,而不能插入其他操作。

-----EOF-----

Categories: 汇编 Tags: 汇编 底层 寄存器