对于80x86 CPU 执行div 等除法指令的时候,如果发生了除法溢出错误,将产生中断类型码为0的中断信息,CPU将检测到这个信息,然后引发中断过程,转去执行0号中断所对应的中断处理程序。
中断处理程序 inter.asm 如下:
assume cs:code
code segment
main:
mov ax,cs
mov ds,ax
mov ax,offset print
mov si,ax ;设置中断处理程序的源地址
mov ax,0020h
mov es,ax
mov di,0 ;设置安全内存地址空间的地址
mov cx,offset pend - offset print ;设置传输信息的长度
cld ;设置传输方向为正
rep movsb ;循环传输字符cx次
mov ax,0 ;设置中断向量表(帮助:80x86CPU中规定向量表存放在0000:0000到0000:03e8的1000个内存单元中,一个表项占4个字节)
mov es,ax
mov word ptr es:[0*4],200h ;低地址存放IP
mov word ptr es:[0*4+2],0h ;高地址存放CS
mov ax,4c00h
int 21h
print: push ax
push cx
push si
push di
push es
jmp short s ;要跳过自定义的数据区,否则会被cpu解析为代码执行的!
adr:db 'Error:division overflow!',0 ;自定义显示信息
s: mov ax,0b800h+1*160+20*2 ;显存开始位置b800:0000
mov es,ax
mov di,0
mov ax,200H + offset adr - offset print ;注意此处:是在安全内存中的偏移地址
mov si,ax
mov ax,cs
mov ds,ax
mov ax,0
mov ah,24h
mov cx,0
s0:
mov cl,ds:[si]
jcxz ok
mov es:[di],cl
mov es:[di+1],ah
inc si
add di,2
jmp short s0
ok:
pop es
pop di
pop si
pop cx
pop ax
mov ax,4c00h ;如果换用iret的话,中断处理完后,原程序会从产生中断的语句处继续运行,在此程序中,则会陷入死循环
int 21h
pend: nop
code ends
end main
测试程序 test.asm 如下:
assume cs:code
code segment
main: mov ax,1000h
mov bl,1
div bl ;因为是8位除数,所以进行8位的除法运算。即ax中为被除数。其结果ah存放余数,al存放商。
mov ax,4c00h
int 21h
code ends
end main
测试结果如下图所示: