Interrupts and Exceptions
Interrupts and Exceptions
com hpc computing solutions to enhance their speed, efficiency, and ability to
tackle sophisticated high level analytics.
(E)IP registers which are pushed on the stack, point to the address of the instruction, which generated the exception. This gives the
exception handler a chance to fix the condition which caused the exception to occur, before restarting the faulting instruction. Traps
are similar to interrupts in the sense that they make the processor push the address of the next instruction to the stack, while aborts
neglect to specify the location of the faulting instruction, since they are usually used to indicate severe errors (such as hardware
errors or illegal system tables) which are not recoverable.
Real-Mode
Software Interrupts
If you've ever programmed for DOS, you probably know that the INT 21h interface has a salient importance in linking applications
with operating system services. For instance, calling an operating system function for opening a file, simply requires issuing an INT
21h interrupt with the correct parameters set in the processor registers.
The BIOS (Basic Input Output System) uses a similar software communication mechanism. The INT 10h, 13h and 16h are all
interfaces to internal BIOS functions, which control the screen, the disk controller and the keyboard. Instead of accessing hardware
devices directly, DOS uses the BIOS services to control the operation of the system. Modern operating systems such as Windows NT
drop their reliance upon the BIOS in favor of faster mechanisms (device drivers) for accessing the PC's hardware.
When the processor bumps into an INT instruction, it pushes the address of the next instruction (CS and IP registers) and the
contents of its flags register to the stack and then jumps to execute the interrupt handler. This ensures that when the handler code
ends, the processor returns automatically to the original code stream (the code which was executing before the interrupt occured).
Here are the precise steps taken by the processor when it encounters an INT instruction:
1. Push Flags, CS and IP to the stack (in this order).
2. Multiply interrupt number by 4 and use the resulting number as an offset into the interrupt table (located at the beginning of
the physical address space).
3. Get far address (CS and IP) of the interrupt handler from the table entry.
4. Disable interrupts (note that if you wish hardware interrupts to be serviced even when the processor executes inside an
interrupt handler, you must issue a STI instruction at the beginning of the handler code).
5. Jump to execute the handler.
6. When the handler code ends (an IRET instruction is executed), pop CS, IP and the flags from the stack so that control returns to
the currently active application.
Many applications (especially TSRs - Terminate and Stay Resident programs) hook software interrupts to supply additional services
on top of those offered by DOS and the BIOS. One good example is Netware 3.1, which hooks INT 21h in order to add support for
network file operations (such as reading a file located on a remote computer). Other pieces of code (mostly device drivers) hook
hardware interrupts to monitor various devices and ensure their proper operation.
To hook an interrupt, a program need only to replace a specific interrupt table entry with the address of its own interrupt handler.
Whenever this interrupt occurs, the handler is automatically invoked by the processor. A good programming practice is to place a call
to the previous handler inside the interrupt handling function. This ensures that all previously installed hooks will get a chance to
handle the incoming interrupt.
Note that when loading an application which uses software interrupts to call operating system services, there is no need to patch the
application code with the actual memory addresses of the OS services. Therefore, the operating system can freely relocate its
services in memory by simply updating the corresponding interrupt table entries with the new addresses.
Hardware Interrupts
Hardware interrupts are not very different in behavior. But still, when considering the path traveled by a hardware interrupt from the
instant it leaves the hardware device until it reaches the processor, you must take into account the actions taken by the interrupt
controller (or the 8259A if you prefer).
When the processor executes an INT instruction, it retrieves the interrupt code from the opcode itself. This code is later used by the
processor to index the IVT (interrupt vector table) and find the address of the interrupt handler. On the other hand, when a hardware
interrupt is detected, the interrupt controller sends the interrupt code to the processor via the data bus. When the code is finally
acquired by the processor (either from the INT opcode or from the interrupt controller) the steps taken are equivalent to those
discussed earlier.
Table 1 presents the interrupt vectors occupied by the interrupt controller chips under different operating systems:
OS
Vectors occupied by
the slave 8259A
DOS
8h - Fh
70h - 77h
Windows
95 / 98
50h - 57h
58h - 5Fh
Windows
NT
30h - 37h
38h - 3Fh
Exceptions
When executing in real-mode, the following exceptions are supported:
Exception Vector
Division
by Zero
Debug /
Single
Step
Condition
Breakpoint
Double
Fault
Stack
Exception
12
Overflow
Bounds
Check
Invalid
Opcode
Device
Not
Available
CS, DS,
ES, FS, GS
Segment
Overrun
FloatingPoint Error
13
16
Condition
Invalid
Task State
Segment
10
Segment
Not
Present
11
Page Fault
14
Alignment
Check
17
Protected-Mode
Handling interrupts in protected-mode requires setting up a table in memory known as the IDT (Interrupt Descriptor Table). The IDT
is somewhat different from the interrupt vector table that exists in real-mode. Instead of being "stuck" at physical address 0, the
protected-mode IDT can float around in the linear address space with absolute freedom (although it is possible to change the address
of the IVT while in real-mode, it is incompatible with the implementation of the 8086 processor). The linear address of the IDT is
determined by a value set into the IDTR register using the LIDT instruction. Each entry in the IDT is 8 bytes long (as opposed to the 4
bytes entries of the IVT) and can contain one of three gate descriptors:
A task gate - Causes a task switch to occur.
An interrupt gate - Control is transferred to the interrupt handler with interrupts disabled.
A trap gate - Control is transferred to the interrupt handler (the interrupt flag remains unchanged).
The following figure presents the internal structure of a trap gate entry:
Trap and interrupt gates have much in common since they are both used for control transfers between different privilege levels. The
selector and offset fields specified in these gate descriptors are used to locate and execute the interrupt handler code. A control
transfer is only permitted to a code residing in the same or a higher privilege level but never to a lower privileged one.
Software Interrupts
Software interrupts are still widely used by protected-mode operating systems in order to publish their internal services to the
external world. However, most of these interfaces are now wrapped by functions and cannot be accessed directly (although it's
possible, it's not recommended). For instance, Windows NT uses the undocumented interrupt 2Eh to allow control transfers between
its user mode and kernel mode components. Whenever a non-privileged Windows application issues a call to an API function, the
system routes the call until it reaches an INT 2Eh instruction. The IDT gate corresponding to this interrupt points to a handler inside
ntoskrnl, which performs the required privileged operations on behalf of the application. Windows 95 and 98 use a similar technique
to hop between user and kernel mode, but rely upon INT 30h instead of using INT 2Eh.
Hardware Interrupts
Hardware interrupts in protected-mode behave in the same manner as described in the real-mode section. The only major difference
is that when executing in protected-mode, the processor consults its IDT rather than searching the real-mode IVT for the address of
the interrupt handler.
Exceptions
Most of the information which was presented in the previous sections, applies to protected-mode as well. However, exception 13
(General Protection Fault) has a wider meaning in protected-mode and can indicate additional conditions than those defined for realmode.
That's it. More information about the implementation of interrupts and exceptions in protected-mode can be obtained from the