About me
Home
Resumé
CV
Pictures

Course Work
CSE300-FA98

Teaching
Portfolio
CSE240-SP99
CSE207-FA03

Misc
eHarmony
Documents

Tools

Get, Set, and Restore Interrupt Vectors

As we start writing our own interrupt handlers, we will need to replace or chain to interrupts. We will also need to restore the original vectors before we leave our program. If we don't, our code will be reclaimed by the operating system and used for subsequent programs. This isn't so bad, but the interrupt vector will still point to the place where our code was! If that interrupt is generated, it will jump to garbage and try to execute!

So how do we get an interrupt vector? Well, one approach is to allocate some memory in your data or code segment using labels. Next, you can use the DOS service routines to get or set an interrupt. I recommend making a macro for this to save yourself some effort. The following code should help you on your way. Notice that the interrupt routine is simply a FAR procedure. This means we can start writing our interrupt service routines as procedures that we call until we know they work. The only difference is that we need to balance the stack so we must do a pushf before we call the function.

TITLE int_test.asm 
;=======================================================================
; gets, sets, and restores an interrupt vector
;=======================================================================

_DATA SEGMENT USE16 BYTE PUBLIC 'DATA'
_DATA ENDS

_TEXT SEGMENT USE16 WORD PUBLIC 'CODE'
  ASSUME cs:_TEXT, ds:_DATA

      orig80hVector       LABEL DWORD
      orig80hOffset       DW ?
      orig80hSegment      DW ?


  PROC newInt80h FAR        ; this should go in its own module
      iret                  ; or library routine !!!!
  ENDP                      ; notice this is a FAR procedure - required
                            ; for interrupt code that we will write

   Start:
      mov    ax, _DATA
      mov    ds, ax

      ;----------------------------------------------------------------
      ; Get Old Vector
      ;----------------------------------------------------------------
      mov     al, 80h           ; vector to retrieve
      mov     ah, 35h           ; function: get interrupt vector
      int     21h
      mov     cs:orig80hOffset, bx ; save the old seg:off of 80h vector
      mov     cs:orig80hSegment, es


      ;----------------------------------------------------------------
      ; Set New Vector
      ;----------------------------------------------------------------
      mov     dx, OFFSET newInt80h
      mov     ax, SEG newInt80h
      mov     ds, ax            ; ds:dx points to our interrupt routine
      mov     al, 80h           ; interrupt function to get
      mov     ah, 25h           ; function: set interrupt vector
      int     21h

      ;----------------------------------------------------------------
      ; Call our Vector as a procedure (good method of testing...)
      ;----------------------------------------------------------------
      pushf
      call   newInt80h

      ;----------------------------------------------------------------
      ; We could call the old vector, but we don't know what this will do
      ;----------------------------------------------------------------
      ;pushf
      ;call   cs:orig80hVector

      ;----------------------------------------------------------------
      ; Call our Vector as an interrupt
      ;----------------------------------------------------------------
      int     80h

      ;----------------------------------------------------------------
      ; Restore Old Vector
      ;----------------------------------------------------------------
      mov     dx, cs:orig80hOffset
      mov     ax, cs:orig80hSegment
      mov     ds, ax            ; ds:dx points to our interrupt routine
      mov     al, 80h           ; interrupt function to get
      mov     ah, 25h           ; function: set interrupt vector
      int     21h

      ;----------------------------------------------------------------
      ; Exit Program (just like normal :)
      ;----------------------------------------------------------------
      mov   ax, 4C00h           ; function: exit program and return to DOS
      int   21h

_TEXT ENDS


_STACK SEGMENT USE16 STACK 'STACK'
      DW  100 dup(?)
_STACK ENDS

END Start

download the file here

Last Modified: January 26, 1999 - Barry E. Mapen