1. 内中断的产生
以下4中情况会产生内中断:
(1)除法错误。如:div除法溢出
(2)单步运行。如debug中的单步调试
(3)运行into指令。
(4)运行int指令
2. 处理中断信息
中断信息中包括8位的中断类型吗,用来表示要运行的中断程序。可是,一个程序入口要cs和ip,8位不够。这样。系统中就有一个中断向量表保存中断程序的cs和ip,8位中断类型吗表示是中断向量表中的第几个。而且中断向量表存放在 0000:0000到0000:03ff的1024个单元中。
3. 中断过程
比如:div除法溢出 的中断类型是0,产生div除法溢出后。cpu知道中断类型位0,cpu先保存标志位。cs、ip,设置TF=0、IF=0,然后去到中断向量表取出相应中断处理程序的cs和ip(ip=(0*4),cs=(0*4+2)) 然后运行中断程序。
即:
(1)取得中断类型吗N
(2)pushf
(3)TF=0,IF=0
(4)push cs
(5)push ip
(6)(ip)=(N*4),(cs)=(N*4+2)
4. 中断处理程序和iret指令
iret指令相当于:
pop ip
pop cs
pop f
一般中断处理程序的步骤:
(1)保存到寄存器
(2)处理中断
(3)恢复到寄存器
(4)iret
5. 写一个中断处理程序
0中断是div除法溢出比如以下程序debug中就会产生overflow错误,在屏幕上显示“Divide overflow”
assume cs:code
code segment
start:
mov ax,1000H
mov bl,1
div bl
code ends
end start
以下就改动0中断的中断程序。让产生div除法溢出时,在屏幕上显示“Welcome to masm!”
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
mov cx,offset do0end - offset do0 ;计算写入大小
cld
rep movsb ;把do0~do0end的代码写到0:200開始的内存空间中去
mov ax,0
mov es,ax
mov word ptr es:[0*4],200h ;改变0中断的中断向量表,是0中断指向我们要的中断处理程序的位置
mov word ptr es:[0*4+2],0
mov ax,4c00h
int 21h
do0:
jmp short do0start
db 'Welcome to masm!' ;保存要显示的信息
do0start:
mov ax,cs
mov ds,ax
mov si,202h ;设置要显示信息在代码中的位置
mov ax,0b800h
mov es,ax
mov di,12*160+36*2 ;显示的位置
mov cx,16
s:
mov al,[si]
mov es:[di],al
inc si
add di,1
mov al,02h ;显示的颜色等信息
mov es:[di],al
add di,1
loop s
mov ax,4c00h
int 21h
do0end:
nop
code ends
end start
先执行上面代码生成的程序,把中断程序复制到安全的内存中。改变中断向量表。然后debug会发生div除法溢出的程序。就会看到屏幕中间显示绿色 的“Welcome to masm!”。
6. 单步中断
CPU每运行完一条指令后。假设检測到标志寄存器的TF为1,则会产生单步中断,引发中断过程。
单步中断的中断类型吗位1。
过程:
(1)取得中断类型吗1。
(2)标志寄存器入栈,TF,IF设置为0
(3)CS,IP入栈
(4)(IP)=(1*4),(CS)=(1*4+2)
7. 响应中断的特殊情况
普通情况,假设CPU检測到中断信息。就会响应中断。但有特殊情况。
当在运行完向ss寄存器传送的指令后,假设发现中断,CPU不会响应。由于假设ss改变,sp没有改变。ss:sp就不是指向正确的栈顶了。
所以改变ss于改变sp的命令要写在一起
如:
mov ax,1000h
mov ss,ax
mov sp,0