Purpose: zero_division handler  
  ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  ;eg8-7.asm
  ;Purpose: zero_division handler
  ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


     .model small
;-------------------------------------------------------------------------
     .stack
;-------------------------------------------------------------------------
     .code
; Main program
main    proc   near
;reset  interrupt  vector 0
      lea   dx, zdiv    ;set interrupt vector
      mov   ax, seg zdiv
      mov   ds, ax
      mov   al, 0     ;interrupt number
      mov   ah, 25h     ;to reset interrupt vector
      int   21h       ;call DOS

;print introduction message
      mov   ax, @code    ;ds<=code segment
      mov   ds, ax
      mov   dx, ok_msg   ;print introduction
      mov   ah, 9
      int   21h

;simulate zero_division condition
      mov   ax, 1
      mov   dl, 0
      div   dl

; display '# 'after return from interrupt handler zdiv
      mov   ah, 2      ;to display a character
      mov   dl, '#'     ;dl<='#'
      int   21h       ;call DOS

;exit and reside in memory
      mov   ah, 31h     ;to exit and reside
      mov   al, 0     ;return code: 0
      mov   dx, ((prog_len+15)/16)+16   ;dx<=memory paragraph

; for residence
      int   21h      ;call DOS
main endp





;-------------------------------------------------------------------------
; Interrupt Handler zdiv
zdiv   proc   far
     push   ax    ;save registers
     push   bx
     push   cx
     push   dx
     push   si
     push   di
     push   bp
     push   ds
     push   es
     sti

prt_warn:
     mov   ax, @code
     mov   ds, ax
     mov   dx, offset warn_msg   ;print warning
     mov   ah, 9
     int   21h


input:
     mov   ah, 1           ;to accept keyboard input
     int    21h           ;call DOS
     cmp    al, 'c'          ;judge whether 'c'
     je    continue
     cmp    al, 'q'         ;judege whether 'q'
     je    exit

     mov    dx, offset beep      ;beep when illegal input
     mov    ah, 09
     int    21h
     jmp   prt_warn


exit:
     mov    ax, 4cffh
     int    21h
continue:
     mov    dx, offset crlf      ;print CR & LF
     mov    ah, 09
     int   21h
     cli


     pop    es            ;restore registers
     pop    ds
     pop    bp
     pop   di
     pop   si
     pop   dx
     pop   cx
     pop   bx
     pop    ax
     iret               ;interrupt return
zdiv   endp

;------------------------------------------------------------------------

; Data area
ok_msg  db 0dh, 0ah, 'Zero-division Handler installed!'
     db 0dh, 0ah, '$'
warn_msg db 'Zero-division detected, ', 07h
     db 'Continue or Quit(c/q)?$'
beep   db 07h, '$'
crlf   db 0dh, 0ah, '$'
prog_len equ $-main


;------------------------------------------------------------------------
     end main