什么是内中断?
在CUP正在执行指令时,检测到CPU内部产生一个特殊信息,并且可以立即对说接收到的信息进行处理,这种信息,我们叫做内中断。
中断向量表
在产生中断程序时,中断程序会给出一个中断类型码。之后,系统通过中断向量表来查找相应中断类型的入口地址,设置CS,IP,运行相应中断程序。
8086中,中断向量表指定存放在0000:0000内存处,从内存0000:0000到0000:03FF的1024个单元中存放着中断向量表。在中断向量表中,每一个表项存放这一个中断向量,也就是一个中断处理程序的入口。这个入口包括段地址和偏移地址,所以一个表项占用了2个字,高位存放段地址,低位存放偏移地址。
中断过程简述
- 收到中断信息
- (从中断信息中)取得中断类型码
- 标志寄存器的值入栈(因为在中断过程中要改变标记寄存器的值,所以先将其保存在栈中)
- 设置标志寄存器的第八位TF和第九位IF的值为0
- CS的内容入栈
- IP内容入栈
- 从内存地址为(中断类型码 * 4) 和(中断类型码 * 4+2)的两个字单元中读取中断处理程序的入口地址设置为IP和CS
改写0号中断代码实例
对0号中断例程序安装思路
编写一个安装程序,然后将安装程序中0号代码段的相应代码存放到一个内存中永远不会被改变的位置(这里我们选择了中断向量表中0000:0200内存位置)
之后,当我们运行其他程序,触发0号中断,将自动调用我们刚刚编写好的代码。
安装程序
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 ;写入到中断向量表中
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
;0号中断程序
;功能:在屏幕中间显示『overflow!』文字
do0:
jmp short do0Start
db "overflow!"
do0Start: mov ax,cs
mov ds,ax
mov si,202H
mov ax,0b800H
mov es,ax
mov di,12*160+36*2
mov cx,9
s: mov al,[si]
mov ah,01110000B
mov es:[di],ax
inc si
add di,2
loop s
mov ax,4c00H
int 21H
do0end:
nop
code ends
end start
执行程序
调用下面程序,触发0号中断程序
assume cs:code
code segment
;调用中断方法1
;int 0
;调用中断方法2
mov ax,1000H
mov bl,1H
div bl
mov ax,4c00H
int 21H
code ends
end
int指令介绍
int指令,格式为 int n
n为中断类型码,他的功能是引发中断过程,执行过程如下:
- 取中断类型码n
- 标志寄存器入栈,IF=0,TF=0;
- CS,IP入栈
- (IP)=(n * 4),(CS)=(n * 4+2)
DOS和BIOS所提供的中断例程
DOS和BIOS为我们提供了许多的中断例程,我们可以通过int n指令来调用这些例程。在调用这些中断例程的时候,我们通常使用寄存器中存放的值来当作中断例程的参数。
assume cs:code
data segment
db 'Welcome to masm!$',0
data ends
code segment
start:
;设置光标位置
mov ah,2
mov bh,0
mov dh,5
mov dl,12
int 10H
;输出信息到屏幕
mov ax,data
mov ds,ax
mov dx,0
mov ah,9
int 21H
mov ah,4cH
int 21H
code ends
end start