第十二章
内中断
本章概述:
1. 任何一个通用的CPU,比如8086,都具备一种能力,可以在执行完当前正在执行的指令之后,检测到从CPU外部发送过来的或内部产生的一种特殊的信息,并且可以立即对所接收到的信息进行处理。这种特殊的信息,我们可以称其为:中断信息。
2. 中断的意思是指,CPU不再接着(刚执行完的指令)向下执行,而是转去处理这个特殊信息。
3. 中断信息是对几个具有先后顺序的硬件操作所产生的事件的统一描述。
4. “中断信息”是要求CPU马上进行某种处理,并向所要进行的该种处理提供了必备的参数的通知信息。
5. 中断信息可以来自CPU的内部和外部。
一、
内中断的产生
1. 当CPU的内部有什么事情发生的时候,将产生需要马上处理的中断信息。对于8086CPU,当CPU内部有下面的情况发生的时候,将产生相应的中断信息:
1) 除法错误,比如,执行div指令产生的除法溢出;
2) 单步执行;
3) 执行into指令;
4) 执行int指令。
2. 中断信息中包含识别来源的编码,用来让CPU区分中断信息的来源。
3. 8086CPU用称为中断类型码的数据来标识中断信息的来源。
4. 中断类型码为一个字节型数据,可以表示256种中断信息的来源。
5. 我们将产生中断信息的事件,即中断信息的来源,简称为中断源。
6. 以上4种中断源,在8086CPU中的中断类型码如下:
1) 除法错误:0
2) 单步执行:1
3) 执行into指令:4
4) 执行int指令,该指令的格式为int n,指令中的n为字节型立即数,是提供给CPU的中断类型码。
二、
中断处理程序
1. CPU收到中断信息后,需要对中断信息进行处理。而如何对中断信息进行处理。可以由我们编程决定。我们编写的,用来处理中断信息的程序被称为中断处理程序。一般来说,需要对不同的中断信息编写不同的处理程序。
2. CPU在收到中断信息后,应该转去执行该中断信息的处理程序。我们知道,若要8086CPU执行某处的程序,就要将CS:IP指向它的入口(即程序第一条指令的地址)。
3. 中断信息中包含有标识中断源的类型码。根据CPU的设计,中断类型码的作用就是用来定位中断处理程序。
三、
中断向量表
1. 所谓中断向量表,就是中断处理程序的入口地址。展开来讲,中断向量表就是中断处理程序入口地址的列表。
2. CPU用8位的中断类型码通过中断向量表找到相应的中断处理程序的入口地址。
3. 中断向量表在内存中保存,其中存放着256个中断源所对应的中断处理程序的入口。
4. CPU只要知道了中断类型码,就可以将中断类型码作为中断向量表的表项号,定位相应的表项,从而得到中断处理程序的入口地址。
5. CPU用中断类型码,通过查找中断向量表,就可以得到中断处理程序的入口地址。
6. 中断向量表在内存中存放,对于8086PC机,中断向量表指定放在内存地址0处。从内存0000:0000到0000:03FF的1024个单元中存放着中断向量表。由于8086CPU设计上就从这个地方读取中断向量表,所以不能将中断向量表放在别处。
7. 中断向量表中,一个表项存放一个中断向量,也就是一个中断处理程序的入口地址,对于8086CPU,这个入口地址包括段地址和偏移地址,所以一个表项占两个字,高地址字存放段地址,低地址字存放偏移地址。
四、
中断过程
1. 可以用中断类型码在中断向量表中找到中断处理程序的入口。找到这个入口地址的最终目的是用它设置CS和IP,使CPU执行中断处理程序。
2. 用中断类型码找到中断向量,并用它设置CS和IP,这个工作是由CPU的硬件自动完成的。CPU硬件完成这个工作的过程被称为中断过程。
3. CPU收到中断信息后,要对中断信息进行处理,首先将引发中断过程。硬件在完成中断过程后,CS:IP将指向中断处理程序的入口,CPU开始执行中断处理程序。
4. CPU在执行完中断处理程序后,应该返回原来的执行点继续执行下面的指令。所以在中断过程中,在设置CS:IP之前,还要将原来的CS和IP的值保存起来。在适用call指令调用子程序时有同样的问题,子程序执行后还要返回到原来的执行点继续执行,所以,call指令先保存当前CS和IP的值,然后设置CS和IP。
5. 下面是8086CPU在收到中断信息后,所引发的中断过程:
1) (从中断信息中)取得中断类型码;
2) 标志寄存器的值入栈(因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中);
3) 设置标志寄存器的第8位TF和第9位IF的值为0;
4) CS的内容入栈;
5) IP的内容入栈;
6) 从内存地址为中断类型码*4和中断类型码*4+2的两个字单元中读取中断处理程序的入口地址设置IP和CS。
6. CPU在收到中断信息之后,如果处理该中断信息,就完成一个由硬件自动执行的中断过程(程序员无法改变这个过程中所要做的工作)。中断过程的主要任务就是用中断类型码在中断向量表中找到中断处理程序的入口地址,设置CS和IP。
7. 简洁的描述中断过程:
1) 取得中断类型码N;
2) pushf;
3) TF=0,IF=0;
4) push
CS;
5) push
IP;
6) (IP)=(N*4),(CS)=(N*4+2)
在最后一步完成后,CPU开始执行由程序员编写的中断处理程序。
五、
中断处理程序和ire
指令
1. 由于CPU随时都可能检测到中断信息,也就是说,CPU随时都可能执行中断处理程序,所以中断处理程序必须一直存储在内存某段空间之中。而中断处理程序的入口地址,即中断向量,必须存储在对应的中断向量表表项中。
2. 中断处理程序的编写方法和子程序的比较相似,以下是常规的步骤:
1) 保存用到的寄存器;
2) 处理中断;
3) 恢复用到的寄存器;
4) 用iret指令返回。
3. iret指令的功能用汇编语法描述为:
pop
IP
pop
CS
popf
4. iret 通常和硬件自动完成的中断过程配合使用。可以看到,在中断过程中,寄存器入栈的顺序是标志寄存器、CS、IP,而iret的出栈顺序是IP、CS、标志寄存器,刚好和其相对应,实现了用执行中断处理程序前的CPU现场恢复标志寄存器和CS、IP的工作。iret指令执行后,CPU回到执行中断处理程序前的执行点继续执行程序。
六、
除法错误中断的处理
当CPU执行div等除法指令的时候,如果发生了除法溢出错误,将产生中断类型码为0的中断信息,CPU将检测到这个信息,然后引发中断过程,转去执行0号中断所对应的中断处理程序。
七、
编程处理0
号中断
1. 内存0000:0000~0000:03FF,大小为1KB的空间是系统存放中断处理程序入口地址的中断向量表。8086支持256个中断,但是,实际上,系统中要处理的中断事件远没有达到256个。所以在中断向量表中,有许多单元是空的。
2. 中断向量表是PC系统中最重要的内存区,只用来存放中断处理程序的入口地址,DOS系统和其他应用程序都不会随便使用这段空间。可以利用中断向量表中的空闲单元来存放我们的程序。一般情况下,从0000:0200至0000:02FF的256个字节的空间所对应的中断向量表项都是空的,操作系统和其他应用程序都不占用。
八、
安装
1. 可以使用movsb指令,将do0的代码送入0:200处。程序代码如下:
assume
cs:code
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
2. 用编译器计算do0的长度:mov cx,do0end-offset d00
九、
do0
十、
设置中断向量
mov ax,0
mov es,ax
mov word ptr es:[0*4],200h
mov word ptr es:[0*4+2],0
十一、
单步中断
1. 基本上,CPU在执行完一条指令之后,如果检测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。单步中断的中断类型码为1。
2. Debug提供了单步中断的中断处理程序,功能为显示所有寄存器中的内容后等待输入命令。然后,在使用t命令执行指令时,Debug将TF设置为1,使得CPU工作于单步中断方式下,则在CPU执行完这条指令后就引发单步中断,执行单步中断的中断处理程序,所有寄存器中的内容被显示在屏幕上,并且等待输入命令。
3. 为了避免在中断处理中再次引发该中断,在进入中断处理程序之前,设置TF=0。
4. CPU提供单步中断功能是为单步跟踪程序的执行过程,提供了实现机制。
十二、
响应中断的特殊情况
1. 一般情况下,CPU在执行完当前指令后,如果检测到中断信息,就响应中断,引发中断过程。可是,在有些情况下,CPU在执行完当前指令后,即便是发生中断,也不会响应。
2. 在执行完向ss寄存器传送数据的指令后,即便是发生中断,CPU也不会响应。这样做的主要原因是,在ss:sp联合指向栈顶,而对它们的设置应该连续完成。如果在执行完设置ss的指令后,CPU响应中断,引发中断过程,要在栈中压入标志寄存器、CS和IP的值。而ss改变,sp并未改变,ss:sp指向的不是正确的栈顶,将引发错误。所以CPU在执行完设置ss的指令后,不响应中断。这连续设置ss和sp指向正确的栈顶提供了一个时机。即,我们应该利用这个特性,将设置ss和sp的指令连续存放,使得设置sp的指令紧接着设置ss的指令执行,而在此之间,CPU不会引发中断过程。
实验12编写0号中断的处理程序