The address of an interrupt

The address of an interrupt can be taken from the interrupt vector table in low memory at address 0000:0000h. This table has the addresses of all 256 interrupts (00h-FFh). Each address takes 4 bytes in the table so the table is 1024 (1k) bytes long. If you want to know the address of a specific interrupt, then get the dword at 4 x n where n is the interrupt wanted. Example: If I want the address of interrupt 21h, I would get the dword at offset 84h (132d) in the table. Remember that these 4 bytes are in little-endian format.

Once you have the segment and offset of that interrupt you can use DEBUG to see the code that makes up that interrupt. For example: If we find that interrupt 21h is at 1234:5678h, then we could start DEBUG and type in at the (-) prompt: u 1234:5678. This would display the first part of the code for the DOS interrupt 21h. You could then follow each jump, call, and so-on to find out how DOS does everything it does.

I have included a small routine in assembly that displays the address of each interrupt from the vector table at 0000:0000h. It is called IVECT.ASM and was assembled to a 418 byte COM file. It prints about 3 or 4 lines per interrupt to the screen, so to view all of the text either press the pause key (pause or Ctrl-S) or redirect the text to a file. i.e.: using IVECT > IVECT.TXT at the DOS prompt will redirect the text to the file named IVECT.TXT

Version 1.10b includes a minor addition. It now displays if the interrupt is being used.

Version: 1.10b
Author: Ben Lunt (Forever Young Software)
Date: 8 Dec 1998
Assembler: NBASM
; This is a small util. to display the segment address of
; each interrupt vector.  You can take this address of
; a given interrupt number and use it in DEBUG with the
; -u command to view the code of this interrupt.

.model tiny
.code
.186
           org  100h
start:     mov  ax,cs                   ; free unused part of Mem Block
           mov  es,ax                   ;   for .COM file format
           mov  bx,4096                 ;
           mov  ah,4Ah                  ;
           int  21h                     ;

           mov  si,offset StartIt       ; display start up string
           call prtstring               ;

           xor  bx,bx                   ; make es:bx point to 0000:0000
           mov  es,bx

           mov  cx,256                  ; 256 interrupts (00-FF)
MainLoop:  push cx
           mov  si,offset InvectS       ; display string
           call prtstring               ;
           mov  al,CIntVNum             ; display current int number
           call prthexs                 ;
           inc  byte CIntVNum           ; inc for next time
           mov  dl,'h'                  ; print 'h'
           mov  ah,02                   ;
           int  21h                     ;
           mov  si,offset InINumS       ; display string
           call prtstring               ;
           mov  ax,es:[bx]              ; get interrupt vector address
           inc  bx                      ;  offset first (little endian)
           inc  bx                      ;
           push ax                      ;
           mov  ax,es:[bx]              ;  segment second (little endian)
           mov  cx,ax                   ;  save segment
           inc  bx                      ;
           inc  bx                      ;
           call prthex                  ; and print segment
           mov  dl,':'                  ; print ':'
           mov  ah,02                   ;
           int  21h                     ;
           pop  ax                      ;
           push ax                      ; save offset for IRET test
           call prthex                  ; print offset
           mov  dl,'h'                  ; print 'h'
           mov  ah,02                   ;
           int  21h                     ;
           cmp  cx,0F000h               ; if segment => F000h then in ROM-BIOS
           jb   short NotinBIOS         ;
           mov  si,offset InBIOSS       ;
           call prtstring               ;
NotinBIOS: pop  si                      ; restore offset
           push es                      ;
           mov  es,cx                   ; see if IRET
           mov  al,es:[si]              ;
           pop  es                      ;
           cmp  al,0CFh                 ; is it IRET
           jne  short NotIRET           ;  if so, then not used
           mov  si,offset NotUsedS      ;
           call prtstring               ;
NotIRET:   mov  si,offset CRLF          ;
           call prtstring               ;
           pop  cx                      ;
           loop MainLoop                ;
Done:      mov  ah,4Ch                  ; exit to DOS
           int  21h                     ; 


prtstring  proc near uses ax dx si
ps1:       mov  dl,[si]                 ; Get character
           inc  si                      ; Point to next one
           or   dl,dl                   ; End of string?
           jz   short ps2               ; Yes, so exit
           mov  ah,02h                  ; Output a character
           int  21h
           jmp  short ps1               ; Keep doing it
ps2:       ret
prtstring  endp

PrtHexs    proc near uses ax bx dx cx
           mov  bx,offset Hex
           push ax
           shr  al,04h
           xlatb
           mov  dl,al
           mov  ah,02
           int  21h
           pop  ax
           and  al,0Fh
           xlatb
           mov  dl,al
           mov  ah,02
           int  21h
           ret
PrtHexs    endp

PrtHex     proc near uses ax bx cx dx
           mov  bx,offset Hex
           mov  cx,04h
HexLoop:   push ax
           mov  al,ah
           shr  al,04h
           xlatb
           mov  dl,al
           mov  ah,02
           int  21h
           pop  ax
           shl  ax,04h
           loop HexLoop
           ret
PrtHex     endp

CIntVNum   db  00h

StartIt    db  13,10,'Interrupt Vector Display Util        Version   01.10b'
           db  13,10,'Forever Young Software   Copyright 1984-2024',13,10,10,0
InvectS    db  13,10,'   Interrupt Vector Number:  ',0
InINumS    db  13,10,'        at segment address:  ',0
InBIOSS    db  13,10,'     In ROM-BIOS memory area.',0
NotUsedS   db  13,10,' Interrupt not used.',0
CRLF       db  13,10,0
Hex        db  '0123456789ABCDEF'

.end  start