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)