Programming the INT 24h error handler
INT24H.ASM allows you to use your own error handler in your program instead of the normal abort, ignore, retry.
Version: 1.00
Author: Ben Lunt (Forever Young Software)
Date: 21 Jan 2000
;
; assembled with NBASM
;
.model tiny
.code
.186
org 100h
start: mov ax,3524h ; get and save original vector
int 21h ;
mov OldSeg,es ;
mov OldOff,bx ;
mov ax,2524h ; set int24h vector to our handler
mov dx,offset OurHandler ;
int 21h ;
call DoErr ; make an error (deliberately)
mov ax,2524h ; restore settings
mov dx,OldOff ;
mov ds,OldSeg ;
int 21h ;
Done: mov ah,4Ch ; exit to DOS
int 21h ;
DoErr proc near uses ax dx ; make an error (deliberately)
mov ah,19h ; get disk drive
int 21h ;
push ax ; and save it for later
mov ah,0Eh ; set drive to a:
xor dl,dl ;
int 21h ;
mov ah,39h ; try to change a dir to on drv a:
mov dx,offset testfile ;
int 21h ;
pop dx ; restore current drive
mov ah,0Eh ;
int 21h ;
ret ;
DoErr endp
OurHandler proc near ; our handler
pusha ; save all registers
mov ax,cs ; make sure ds = cs
mov ds,ax ;
mov dx,offset OurErrS ; we can make it do what we want
mov ah,09h ; as long as we don't use non-
int 21h ; conventional interrupts
popa ; restore registers
xor al,al ; tell DOS 'NO ERROR'
iret ; interrupt return
OurHandler endp
; this must be in code segment for our handler to work
;
OurErrS db 'This should print when our error handler is active',36
OldSeg dw 00h
OldOff dw 00h
testfile db 'testcd',0
.end start
** Some info on a int24h handler **
DOS restores the INT24h handler on exit of your program. Because of this, you can not make a TSR and have DOS use your interrupt handler.
You must be careful using the stack in your handler. Unless you have a complicated handler, you shouldn't have to worry about the stack too much. Just remember that your handler uses the stack from your original program (the calling program). So if your handler needs a large stack, make sure your calling program has enough to support it. If you don't do much more than a PUSHA and POPA, then you should be fine.
If your handler will require a larger stack, then you will have to create one. See my TSR demo page for more info on this.
You can use most of the MSDOS interrupts that don't produce a critical error. If you use an DOS interrupt that produces a critical error while in your error handler, then you could/will get very strange results and even crash your system.
However, DOS is not reenterent. i.e.: You can not call a DOS function within a DOS function. If you have a big handler that calls a lot of DOS functions, I would recommend hooking the INT 28h and INT 08h handlers as well, so you don't crash the machine. Again, see my TSR demo page for more info on this.
If you need to use data, then put this data in the code segment near this routine. Make sure that ds = cs.
If you need anymore help on the INT24h handler, send me some email.
********* Just for fun.
You can look at the code that DOS uses for its own int24h handler. Each int vector has a length of 4 bytes (a word for the segment and a word for the offset.)
Since int24h vector is the 36th vector, multiply this by 4 (size of each vector) and this is where the address is for this interrupt.
36 * 4 = 144 (90h)(see below)
To get the interrupt vector address of int 24h, use debug and at the (debug) prompt type (where (enter) is the enter key):
d 0000:0090 L 4 (enter)
this will display 4 numbers (in hex)
01 02 03 04
(please note that these numbers will not be the same for each session and that I use 1 - 4 as an example. Also remember that these are in Little-Endian format (Intel style))
So now we know where in memory DOS's int 24h code is. Now use the following line to view this code:
u 0403:0201 (enter) (make sure the replace the numbers with your own results from above)
This will display the first few lines of code for int 24h. To view some more, just enter a 'u' and the <enter> key.
u (enter)