目录
一、中断
中断指CPU检测到从外部发送过来的或内部产生的一种特殊信息,于是不再接着向下执行,而是转去处理这个特殊信息。
二、内中断
1.内中断的产生
当CPU有以下几种情况发生的时候,将产生对应的中断信息。而8086CPU用中断类型码标识终端信息的来源。中断类型码为一个字节型数据,可以表示256种中断信息的来源。
(1)除法错误:0
(2)单步执行:1
(3)执行into指令:4
(4)执行int指令,该指令的格式为int n,n为字节型立即数,是提供给CPU的中断类型码
2.内中断的处理
(1)中断处理程序
中断处理程序就是对终端信息进行处理的程序。
CPU收到中断信息后,应该转去执行处理程序。
(2)中断向量表
如何设置CS:IP指向程序入口?
用中断向量表。
对于8086PC机,中断向量表指定放在内存地址0处,其中存放着256个中断源所对应的中断处理程序的入口。
一个表项占2个字(4个字节),高地址放段地址,低地址放偏移地址。
(3)中断过程
由于执行完中断处理程序后,还要返回原来的执行点继续执行下面的指令,所以应该先保存CS和IP
过程如下:(2,3步以后会学到)
1)取得中断类型码N
2)pushf
3)TF=0,IF=0
4)push CS
5)push IP
6)(IP)=(N*4),(CS)=(N*4+2)
(4)中断处理程序的编写方法
1)保存用到的寄存器
2)处理中断
3)恢复用到的寄存器
4)用iret指令返回
iret指令相当于:
pop IP
pop CS
popf
三、编程处理0号中断
任务:重新编写一个0号中断处理程序,在屏幕中间显示"overflow",然后返回操作系统。
分析:
将中断处理程序称为do0,则应将do0放在内存某处,并且将中断向量表的0号表项改为do0的入口地址。
do0放在哪里呢?
已经知道中断向量表在0000:0000-0000:03FF,系统要处理的中断事件远没有达到256个,所以有许多单元是空的,一般0000:0200-0000:02FF的256个字节的空间所对应的中断向量表项都是空的,所以可以将do0传送到内存0000:0200处。
如何传送?可以用以前学过的movsb指令,结合rep指令。
程序如下:
assume cs:code
code segment
start: mov ax,cs
mov ds,ax
mov si,offset do0
mov ax,0
mov es,ax
mov di,200h ;ds:si指向被复制的起始单元,es:di指向要复制到的位置
mov cx,offset do0end-offset d0 ;设复制的内容的长度
cld ;设置传输方向为正
rep movsb ;开始传输/复制
;设置中断向量表
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!'
do0start: mov ax,cs
mov ds,ax
mov si,202h ;设置ds:si指向字符串(jmp指令占2个字节)
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
doend: nop
code ends
end start
四、单步中断
1.单步中断机制
CPU在执行完一条指令之后,如果检测到标志寄存器的TF位为1,则产生单步中断,引发中断过程,转去中断处理程序。
2.提供单步中断功能的原因
为单步跟踪程序的执行过程,提供了实现机制。(debug)
3.debug如何利用单步中断功能
首先,debug提供了单步中断的中断处理程序,功能为显示所有寄存器的内容后等待输入命令。
在使用t命令执行指令时,Debug将TF设置为1,使CPU工作于单步中断方式下,执行中断处理程序。
在进入中断处理程序之前,设置TF=0(否则中断执行程序也会引发单步中断,不断循环)
所以中断过程为:
(1)取得中断类型码N
(2)标志寄存器入栈,TF=0、IF=0
(3)CS、IP入栈
(4)(IP)=(N*4),(CS)=(N*4+2)
五、响应中断的特殊情况
有些情况下,CPU在执行完当前指令后,即便是发生中断,也不会响应。
例如,在执行完ss寄存器传送数据的指令后,即便是发生中断,CPU也不会响应。因为ss:sp联合指向栈顶,而对它们的设置应该连续完成。
我们应该利用这个特性,将设置ss和sp的指令连续存放,如下:
mov ax,1000h
mov ss,ax
mov sp,0
而不应该如下:
mov ax,1000h
mov ss,ax
mov ax,0
mov sp,0