您的位置:首页 > 编程语言

div溢出中断处理代码

2012-06-13 15:48 218 查看
assume cs:code,ds:data,ss:stack
data segment
db 'back to main programs!',0
data ends
stack segment
dw 64 dup (0)
stack ends
code segment
start:mov ax,stack
mov ss,ax
mov sp,128

mov ax,0
mov es,ax
mov di,0200h

mov ax,cs
mov ds,ax
mov si,offset do0
mov cx,offset over
sub cx,si

cld
rep movsb    ;安装完毕

mov dx,0
mov ax,0200h
mov es:[0],ax
mov es:[2],dx  ;中断向量设置完毕

mov dx,1     ;测试中断程序
mov ax,0
mov bx,1
div bx

mov ax,data
mov ds,ax
mov si,0

mov ax,0b800h
mov es,ax
mov di,14*160+32*2
s0:mov cl,[si]
mov ch,0
jcxz ok0
mov ch,42h
mov es:[di],cx
add di,2
inc si
jmp short s0

ok0:mov ax,4c00h
int 21h

do0:jmp short begin
db 'overflow!',0
begin:push ax
push cx
push dx
push ds
push es
push si
push di

pushf
pop ax
or ax,0100h
push ax
popf
mov ax,cs
mov ds,ax
mov si,0202h

mov ax,0b800h
mov es,ax
mov di,12*160+32*2
s:mov cl,[si]
mov ch,0
jcxz ok
mov ch,42h
mov es:[di],cx
add di,2
inc si
jmp short s
nop
ok:mov di,sp       ;恢复了其他寄存器,这时候栈顶才是要返回的地址,但是这又破坏了要保护的寄存器。。
add di,14       ;直接根据保护的寄存器数目定位到要找的返回地址
mov si,ss:[di]  ;修改之前div处的指令为两个nop,使div引起的中断可以返回到原程序
mov ax,ss:[di+2]
mov es,ax
mov es:[si],9090h
pop di
pop si
pop es
pop ds
pop dx
pop cx
pop ax

iret

;ok:mov ax,4c00h
; int 21h
over:nop
code ends
end start

因为div溢出引起的中断其实不因该返回原来引起中断的程序。直接在中断处理程序就结束。这里为了说明问题对中断处理程序做了改动。主要有如下:

1.中断处理程序里设置了TF标志,即允许单步中断,方便调试。这相当于debug下的T命令,将TF标志设置为1 。因为DIV溢出中断和单步中断属于不同的中断,所以不会引起像在T中断出现的无限循环处理执行中断处理程序第一条指令。

2.发生中断时,将引起中断的指令的cs:ip存入栈中,然后中断处理程序执行完毕,如果中断处理程序不使程序结束,而试图使用iret返回引起中断的指令,则回到引起中断的指令会再次引起中断。这里,我们在中断处理程序内对引起中断的指令进行了修改,改为两个空转指令,这样就可以安全返回原程序了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: