中断的意思是指,CPU不再接着(刚执行完的指令)向下执行,而是转去处理这个特殊信息。
对于8086CPU,当CPU内部有下面情况发生的时候,将产生相应的中断信息:
– 除法错误:比如div指令产生的除法溢出。
– 单步执行
– 执行into指令
– 执行int指令
标识中断信息来源的数据称为中断类型码,为一个字节型数据,可表示256种中断信息来源。
在8086CPU中的中断类型码:
– 除法错误:0
– 单步执行:1
– 执行into指令:4
– 执行int指令:指令格式int n
,指令中的n为字节型立即数,提供CPU的中断类型码。
中断向量表
CPU用8位的中断类型码通过中断向量表找到相应的中断处理程序的入口。中断向量表就是中断处理程序入口地址的列表。
8086CPU中,中断向量表指定存放在内存0地址处,从内存的0000:0000到0000:03FF的1024个单元。高地址字存放段地址,低地址字存放偏移地址。
中断过程
CPU收到中断信息后,所引发的中断过程
1. 从中断信息中取得中断类型码
2. 标志寄存器的值入栈
3. 设置标志寄存器的第8位TF和第9位IF的值为0
4. CS的内容入栈
5. IP的内容入栈
6. 从内存地址为中断类型码*4(IP)
和中断类型码*4+2(CS)
中读取中断处理程序的入口。
用代码形式表示:
1. 取得中断类型码N
2. pushf
3. TF=0,IF=0
4. push CS
5. push IP
6. (IP) = (N*4),(CS) = (N*4+2)
iret指令
中断处理程序的编写步骤:
1. 报错用到的寄存器
2. 处理中断
3. 恢复用到的寄存器
4. 用iret指令返回
iret指令的功能用汇编语法描述为:
pop IP
pop CS
popf
在中断过程中,寄存器入栈的顺序是标志寄存器、CS、IP,而iret的出栈顺序是IP、CS、标志寄存器。
中断实例
重新编写一个对0号中断(除法错误)的处理,他的功能是在屏幕中间显示“overflow!”后,然后返回操作系统。
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指向目的地址0000:0200h
mov cx,offset do0end-offset do0 ;设置cx为do0-do0end的长度
cld ;设置传输方向为正
rep movsb
;以上部分将标号do0到标号do0end之间的内容送到0000:0200h处
mov ax,4c00h
int 21h
do0: jmp short do0start
db "overflow!"
do0start: mov ax,cs
mov ds,ax
mov si,202h ;设置ds:si指向字符串(jmp指令占两字节)
mov ax,0b800h
mov es,ax
mov di,12*160+36*2 ;设置es:di指向显存空间的中间位置
mov cx,9 ;设置cx为字符串长度
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,他的中断过程:
1. 取得中断类型码1
2. 标志寄存器入栈,TF、IF设置为0
3. CS、IP入栈
4. (IP) = (1*4),(CS) = (1*4+2)
接下来的问题是:当TF=1时,CPU在执行完一条指令后将引发单步中断,转去执行中断处理程序。注意,中断处理程序也是由一条条指令组成的,如果在执行中断处理程序之前,TF=1,那么将会发生死循环。所以中断过程要有TF=0这个步骤。