一、内中断的产生
8086CPU使用单元字节大小的数字来标识中断类型。
CPU内部可能产生多种多样的中断,那么应该如何来标识是哪种中断呢,或者说我们如何确定中断源?
8086CPU用称为中断类型码的数据来标识中断信息的来源。中断类型码为一个字节型数据,可以表示256种中断类型。以后,我们将产生中断信息的事件,即中断信息的来源,称之为中断源。
二、中断处理程序
处理中断信息的程序被称为中断处理程序
三、中断向量表
实际上,8086CPU用8位的中断类型码通过中断向量表找到相应的中断处理程序的入口地址。中断向量表就是中断处理程序入口地址的列表,列表的下标索引(从0开始)即是中断类型码的值。中断向量表实际上是中断类型码与中断处理程序入口地址之间的一种映射关系
8086CPU中断向量表指定放在内存0处。每个表项占用4个字节,高位字存放段地址,低位字存放偏移地址
四、中断过程
用中断类型码找到中断向量,并用它设置CS和IP的值,这个工作是由CPU的硬件自动完成的。CPU硬件完成这个工作的过程被称为中断过程。中断过程完成后,CPU就会开始执行中断处理程序。中断过程可以理解为中断环境的初始化。那么在CPU进行中断过程中需要准备哪些工作呢?概括来说,主要进行以下六步准备工作:
(1)(从中断信息中)取得中断类型码;
(2)标志寄存器的值入栈(因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中);
(3)设置标志寄存器的第8位TF和第9位IF的值为0(这一步的目的后面将介绍);
(4)CS的内容入栈;
(5)IP的内容入栈;
(6)从内存地址为中断类型码4和中断类型码4+2的两个字单元中读取中断处理程序的入口地址设置IP和CS。
五、中断处理程序和iret指令
中断处理程序必须一直存储在指定内存中,以应对随时可能发生的中断事件。
中断处理程序的编写方法和子程序比较相似,下面是常规步骤:
(1)保存用到的寄存器;
(2)处理中断;
(3)恢复用到的寄存器;
(4)用 iret 指令返回。
iret指令的功能用汇编语法描述为:
pop IP pop CS popf
在中断过程中,注意标志寄存器入栈和出栈的次序。入栈顺序是标志寄存器、CS、IP,出栈顺序与此相反
六、编程处理0号中断
我们的需求是重新编写一个0号中断处理程序,它的功能是在屏幕中间显示“overflow!”,然后返回到操作系统。
为了满足以上需求,需要做一下几件事情:
(1)编写可以显示“overflow”的中断处理程序:do0;
(2)将do0送入内存0000:0200处;
(3)将do0的入口地址0000:0200存储在中断向量表0号表项中。
程序的框架如下:
code segment start: do0安装程序 设置中断向量表 mov ax, 4c00h int 21h do0: 显示字符串"overflow" mov ax, 4c00h int 21h code ends end start
七、安装
所谓安装就是将中断处理程序(do0)送到指定内存处
安装程序的框架如下所示:
code segment start: 设置es:di指向目的地址 设置ds:si指向源地址 设置cx为传输长度 设置传输方向为正 rep movsb 设置中断向量表 mov ax, 4c00h int 21h do0: 显示字符串"overflow!" mov ax, 4c00h int 21h code ends end start
八、do0
do0程序即是我们的0号中断处理程序。其主要目的是显示字符串"overflow!"。
主要程序代码如下所示:
do0: jum short do0start db 'overflow!' do0start: mov ax, cs mov ds, ax mov si, 202h mov ax, 0b800h mov es, ax mov di, 12*160 + 36*2 mov cx, 9 s:mov al, [si] mov es:[di], al inc si add di, 2 loop s mov ax, 4c00h int 21h do0end: nop
九、设置中断向量
设置中断向量,也即是将中断处理程序do0在内存中的入口地址存放在中断向量表0号表项中。0号表项的地址为0:0,其中0:0字单元存放中断处理程序入口地址的偏移地址,0:2字单元存放中断处理程序入口地址的段地址。程序如下:
mov ax, 0 mov es, ax mov word ptr es:[0*4], 200h mov word ptr es:[0*4+2], 0
十、单步中断
基本上,在CPU执行完一条指令之后,如果检测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。单步中断的中断类型码为1。在一开始我们说CPU在执行中断处理程序之前要先将标志寄存器TF位置0,这就是为了防止CPU在执行1号类型中断(单步中断)时无限递归执行中断。
CPU提供单步中断功能的出发点是,为单步跟踪程序的执行过程,提供了实现机制。