Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Peter Norton Programmer's Guide - Norton Guide http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]

  The main programming interest in interrupt vectors is not to read them but
  to change them to point to a new interrupt-handling routine. To do this,
  you must write a routine that performs a different function than the
  standard ROM BIOS or DOS interrupt handlers perform, store the routine in
  RAM, and then assign the routine's address to an existing interrupt in the
  table.

  A vector can be changed byte by byte on an assembly-language level, or by
  using a programming-language instruction like the POKE statement in BASIC.
  In some cases, there may be a danger of an interrupt occurring in the
  middle of a change to the vector. If you are not concerned about this, go
  ahead and use the POKE method. Otherwise, there are two ways to change
  a vector while minimizing the likelihood of interrupts: by suspending
  interrupts during the process, or by using a DOS interrupt specially
  designed to change vectors.

  The first method requires that you use assembly language to suspend
  interrupts while you change the interrupt vector. You can use the clear
  interrupts instruction (CLI), which suspends all interrupts until a
  subsequent STI (set interrupts) instruction is executed. By temporarily
  disabling interrupts with CLI you ensure that no interrupts can occur
  while you update an interrupt vector.

  --------------------------------------------------------------------------
  NOTE:
    CLI does not disable the nonmaskable interrupt (NMI). If your
    application is one of the rare ones that needs to supply its own NMI
    handler, the program should temporarily disable the NMI while changing
    the NMI interrupt vector. (See PC or PS/2 technical reference manuals
    for details.)
  --------------------------------------------------------------------------

  The following example demonstrates how to update an interrupt vector with
  interrupts temporarily disabled. This example uses two MOV instructions to
  copy the segment and offset address of an interrupt handler from DS:DX
  into interrupt vector 60H:

  xor     ax,ax                   ; zero segment register ES
  mov     es,ax
  cli                             ; disable interrupts
  mov     word ptr es:[180h],dx   ; update vector offset
  mov     word ptr es:[182h],ds   ; update vector segment
  sti                             ; enable interrupts

  The second method of updating an interrupt vector is to let DOS do it for
  you using DOS interrupt 21H, service 25H (decimal 37), which was designed
  for this purpose. There are two very important advantages to letting DOS
  set interrupts for you. One advantage is that DOS takes on the task of
  putting the vector into place in the safest possible way. The other
  advantage is more far-reaching. When you use DOS service 25H to change an
  interrupt vector, you allow DOS to track changes to any interrupt vectors
  it may itself be using. This is particularly important for programs that
  might run in the DOS "compatibility box" in OS/2. Using a DOS service to
  set an interrupt vector instead of setting it yourself is only one of many
  ways that you can reduce the risk that a program will be incompatible with
  new machines or new operating-system environments.

  The following example demonstrates how to use interrupt 21H, service 25H
  to update the vector for interrupt 60H from values stored in a memory
  variable:

  mov     dx,seg Int60Handler     ; copy new segment to DS
  mov     ds,dx
  mov     dx,offset Int60Handler  ; store offset address in DX
  mov     al,60h                  ; interrupt number
  mov     ah,25h                  ; DOS set-interrupt function number
  int     21h                     ; DOS function-call interrupt

  This example shows, in the simplest possible way, how to use the DOS
  service. However, it glosses over an important and subtle difficulty: You
  have to load one of the addresses that you're passing to DOS into the DS
  (data segment) register--which effectively blocks normal access to data
  through the DS register. Getting around that problem requires you to
  preserve the contents of the DS register. Here is one way this can be
  done. In this example, taken from the Norton Utilities programs, the
  interrupt 09H vector is updated with the address of a special interrupt
  handler:

  push    ds                      ; save current data segment
  mov     dx,offset PGROUP:XXX    ; store handler's offset in DX
  push    cs                      ; move handler's code segment...
  pop     ds                      ; ...into DS
  mov     ah,25h                  ; request set-interrupt function
  mov     al,9                    ; change interrupt number 9
  int     21h                     ; DOS function-call interrupt
  pop     ds                      ; restore original data segment

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson