中断的意思是指CPU不在接着(刚执行的指令)向下执行,而是转去处理这个特殊信息,而这个特殊的信息我们可以称其为中断信息。中断信息是要求CPU马上进行某种处理,并向所要进行的该种处理提供了必备的参数的通知信息。
对于8086CPU,当CPU内部有下面的情况发生的时候,将产生响应的中断信息。
而中断信息中必须包含中断类型码的数据来标识终端信息的来源。中断类型码为一个字节型数据,可以表示256种中断信息的来源。
在8086CPU中的终端类型码如下。
我们编写的,用来处理中断信息的程序被称为中断处理程序。
要想执行中断处理程序如何从8位终端类型码得到处理程序的段地址和偏移地址呢?
中断向量表在内存0000:0000到0000:03FF的1024个单元中保存,其中存放着256个中断信息的来源所对应的中断处理程序的入口,这个入口地址包括段地址和偏移地址,所以一个表项占两个字节,高地址字存放段地址,低地址字存放偏移地址。CPU只要知道了中断类型码,就可以将中断类型码作为中断向量表的表项号,定位相应的表项,从而得到中断处理程序的入口地址。
中断过程就是用中断类型码找到中断向量,并用它设置CS和IP的过程。
下面是8086CPU在收到中断信息后,所引发的中断过程。
更简洁的表述中断过程,如下:
取得中断类型码 N;
pushf
TF=0,IF=0
push CS
push IP
(ip)=(N*4),(CS)=(N*4+2)
中断处理程序的编写方法和子程序的比较相似,下面是常规的步骤:
iret指令的功能用汇编语法描述为:
pop ip
pop cs
popf
iret通常和硬件自动完成的中断过程配合使用。中断过程中,寄存器入栈的顺序和iret刚好相对应。
;因为除法溢出随时可能发生,CPU随时都可能将CS:IP只想程序的入口,执行程序,所以我们将程序放入内存中。
;因为系统要处理的中断事件远没有达到256个,所以在中断向量表中,有许多单元是空的。
assume cs:code
code segment
start:
;安装:将中断处理程序代码送入中断向量表中。
mov ax,cs
mov ds,ax
mov si,offset do0 ;ds:si指向源地址
mov ax,0
mov es,ax
mov di,200h ;es:di指向目的地址
mov cx,offset do0end-offset do0 ;设置cx为传输长度 ;-是编译器识别的运算符号,编译器可以用它来进行两个常数的减法。
cld ;设置传输方向为正
rep movsb
;设置中断向量:将do0的入口地址,写入中断向量表的0号表项中,使do0为0号中断的中断处理程序
mov ax,0
mov es,ax
mov word ptr es:[0*4],200h
mov word ptr es:[0*4+2],0
mov ax,4c00h
int 21h
;中断处理程序代码
do0: jmp short do0start
db "overflow!" ;放在data段执行完后内存被系统释放数据可能被覆盖
do0start:
mov ax,cs
mov ds,ax
mov si,202h ;ds:si指向字符串,复制到0:200处
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
code ends
end start
基本上,CPU在执行完一条指令之后,如果监测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。单步中断的中断类型码为1,则它所引发的中断过程如下。
如上所述,如果TF=1,则执行好一条指令后,CPU就要转去执行1号中断处理程序。