Q. Write an interrupt routine to handle 'division by zero'?
This file can be loaded just like a COM file though makes itself permanently resident until the system is running.
This ISR is splitted into two main sections: initialisation and interrupt handler. The initialisation procedure (INIT) is executed just once when program is executed from DOS level. INIT takes over the type zero interrupt vector and it also prints a sign-on message and then performs a terminate and 'stay resident exit' to MS-DOS. This special exit reserves memory occupied by program so that it's not overwritten by subsequent application programs. The interrupt handler (ZDIV) receives control when a divide-by-zero interrupt takes place.
CR EQU ODH ; ASCII carriage return
LF EQU 0Ah ; ASCII line feed
BEEP EQU 07h ; ASCII beep code
BACKSP EQU 08h ; ASCII backspace code
CSEG SEGMENT PARA PUBLIC 'CODE'
ORG 100h
ASSUME CS: CSEG, DS: CSEG, ES: CSEG, SS: CSEG
INIT PROC NEAR
MOV DX,OFFSET ZDIV ; reset interrupt 0 vector
; to address of new
; handler using function 25h, interrup
MOV AX, 2500h ; 0 handles divide-by-zero
INT 21h
MOV AH,09 ; print identification message
INT 21h
; DX assigns paragraphs of memory
; to reserve
MOV DX, ((OFFSET PGM_LEN + 15)/16) + 10h
MOV AX, 3100h ; exit and stay resident
INT 21h ; with a return code = 0
INIT ENDP
ZDIV PROC FAR ; this is the zero-divide
; Hardware interrupt handler.
STI ; enable interrupts.
PUSH AX ; save general registers
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH DS
PUSH ES
MOV AX, CS
MOV DS, AX
MOV DX, OFFSET WARN ; print warning "divide by
MOV AH, 9 ; zero "and" continue or
INT 21h ; quit?"
ZDIV1: MOV AH, 1 ; read keyboard
INT 21h
CMP AL, 'C' ; is it 'C' or 'Q'?
JE ZDIV3 ; jump it is a 'C'.
CMP AL, 'Q'
JE ZDIV2 ; jump it's a'Q'
MOV DX, OFFSET BAD ; illegal entry, send a
MOV AH, 9 ; beep, erase the bad char
INT 21h ; and try again
JMP ZDIV1
ZDIV2: MOV AX, 4CFFh ; user wants to abort the
INT 21h ; program, return with
; return code = 255
ZDIV3: MOV DX, OFFSET CRLF ; user wishes to continue
MOV AH, 9 ; send CRLF
INT 21h
POP ES ; restore general registers
POP DS ; and resume execution
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
IRET
ZDIV ENDP
SIGNON DB CR, LF, 'Divide by zero interrupt'
DB 'Handler Installed'
DB CRLF,'$'
WARN DB CR, LF, 'Divide by zero detected:'
DB CR, LF 'Quit or Continue (C/Q)?'
DB '$'
BAD DB BEEP, BACKSP, "BACKSP,'$'
CRLF DB CR, LF, $'
PGM_LEN EQU $-INIT
CSEG ENDS
END