When code crashes the cpu normally generates an interrupt (see Intel programmers guides for details). The interrupts are handled by system services. Any system module or driver can try to allocate one or more CPU generated interrupts using system service 0xA7 (and system service 0xAF to de-allocate it). Any code that has allocated interrupts will be called if the interrupt occurs.

Interrupt Types

This is a breif list. For full details see Intel programmers guides.

 00      Divide error
 01      Debug exceptions
 02      Nonmaskable interrupt
 03      Breakpoint (one-byte INT 3 instruction)
 04      Overflow (INTO instruction)
 05      Bounds check (BOUND instruction)
 06      Invalid opcode
 07      Coprocessor not available
 08      Double fault
 09      (reserved by Intel)
 0A      Invalid TSS
 0B      Segment not present
 0C      Stack exception
 0D      General protection
 0E      Page fault
 0F      (reserved by Intel)
 10      Coprecessor error
 11-1F   (reserved by Intel)

Allocating an interrupt

In general this is easy.  For example:

    mov bl,7            ;Coprocessor not available interrupt
    mov cx,cs           ;Code ID for driver or system module
    mov edx,CPUint07    ;Offset to be called
    callMemory 0xA7     ;Standard macro (mov eax,0xA7; call 0x18:0)
    test al,al          ;Was there an error?
    jne error           ; yes

After doing this system services will call your code when the chosen interrupt/s are triggered.

Calls from system services

When a CPU generated interrupt occurs system services calls all code that's allocated that interrupt after doing some pre-processing. Before and after than call certain registers must contain certain information:

  AL     Interrupt status flags
          Bit    Meaning when 1
           0      Interrupted task is restartable
           1      Exception handler is task (interrupted task suspended)
           2-6    Reserved
           7      Cause of interrupt repaired
  AH     Interrupt number
  EBX    Address of task page
  CX     Task ID
  EDX    Error code (or 0)

During the call the address space will be the same as the one in use when the interrupt occured. Routines called by system services in this manner must be re-entrant in case multiple interrupts occur.

When the called code returns it must leave all registers the same as they where when it called except AL. Setting bit 8 of AL will prevent any further exception handlers being called. Setting bit 0 of AL allows the task to be restarted (otherwise the task is terminated).

System services

System services does some strange things that need explaining. A table of up to 16 different far calls to make is kept for when each interrupt occurs. The code indicated by these tables will be called one after the other until the cause is repaired or all code has been called. When system services calls interrupt receivers it should check that the code that caused the interrupt is not the same code it's about to call.

During boot system services starts before time services, so during boot it can't allocate any tasks to interrupts. To get around this the time services should call system service 0xEF when it starts (unless time services is being replaced). If system services is being replaced time services will be present so this isn't necessary an system services should go ahead and create tasks for the relevant IDT descriptors.

Home  Index
Copyright 1998, Brendan Trotter