div溢出中断处理代码

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返回引起中断的指令,则回到引起中断的指令会再次引起中断。这里,我们在中断处理程序内对引起中断的指令进行了修改,改为两个空转指令,这样就可以安全返回原程序了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值