Interrupt descriptor table
In-game article clicks load inline without leaving the challenge.
The interrupt descriptor table (IDT) is a data structure used by the x86 architecture to implement an interrupt vector table. The IDT is used by the processor to determine the memory addresses of the handlers to be executed on interrupts and exceptions.
The details in the description below apply specifically to the x86 architecture. Other architectures have similar data structures, but may behave differently.
The IDT consists of 256 interrupt vectors and the use of the IDT is triggered by three types of events: processor exceptions, hardware interrupts, and software interrupts, which together are referred to as interrupts:
- Processor exceptions generated by the CPU have fixed mapping to the first up to 32 interrupt vectors. While 32 vectors (0x00-0x1f) are officially reserved (and many of them are used in newer processors), the original 8086 used only the first five (0-4) interrupt vectors and the IBM PC IDT layout did not respect the reserved range.
- Hardware interrupt vector numbers correspond to the hardware IRQ numbers. The exact mapping depends on how the Programmable Interrupt Controller such as Intel 8259 is programmed. While Intel documents IRQs 0-7 to be mapped to vectors 0x20-0x27, IBM PC and compatibles map them to 0x08-0x0F. IRQs 8-15 are usually mapped to vectors 0x70-0x77.
- Software interrupt vector numbers are defined by the specific runtime environment, such as the IBM PC BIOS, DOS, or other operating systems. They are triggered by software using the INT instruction (either by applications, device drivers or even other interrupt handlers). For example, IBM PC BIOS provides video services at the vector 0x10, MS-DOS provides the DOS API at the vector 0x21, and Linux provides the syscall interface at the vector 0x80.
Real mode
In real mode, the interrupt table is called IVT (interrupt vector table). Up to the 80286, the IVT always resided at the same location in memory, ranging from 0x0000 to 0x03ff, and consisted of 256 far pointers. Hardware interrupts may be mapped to any of the vectors by way of a programmable interrupt controller. On the 80286 and later, the size and locations of the IVT can be changed in the same way as it is done with the IDT (Interrupt descriptor table) in protected mode (i.e., via the LIDT (Load Interrupt Descriptor Table Register) instruction) though it does not change the format of it.
BIOS interrupts
The BIOS provides simple real-mode access to a subset of hardware facilities by registering interrupt handlers. They are invoked as software interrupts with the INT assembly instruction and the parameters are passed via registers. These interrupts are used for various tasks like detecting the system memory layout, configuring VGA output and modes, and accessing the disk early in the boot process.
Protected and long mode
The IDT is an array of descriptors stored consecutively in memory and indexed by the vector number. It is not necessary to use all of the possible entries: it is sufficient to populate the table up to the highest interrupt vector used, and set the IDT length portion of the IDTR accordingly.
The IDTR register is used to store both the linear base address and the limit (length in bytes minus 1) of the IDT. When an interrupt occurs, the processor multiplies the interrupt vector by the entry size (8 for protected mode, 16 for long mode) and adds the result to the IDT base address. If the address is inside the table, the DPL is checked and the interrupt is handled based on the gate type.
The descriptors may be either interrupt gates, trap gates or, for 32-bit protected mode only, task gates. Interrupt and trap gates point to a memory location containing code to execute by specifying both a segment (present in either the GDT or LDT) and an offset within that segment. The only difference between trap and interrupt gates is that interrupt gates will disable further processor handling of maskable hardware interrupts, making them suitable to handle hardware-generated interrupts (conversely, trap gates are useful for handling software interrupts and exceptions). A task gate will cause the currently active task-state segment to be switched, using the hardware task switch mechanism to effectively hand over use of the processor to another program, thread or process.
Common IDT layouts
Protected-mode exceptions and interrupts
In protected mode, the lowermost 32 interrupt vectors are reserved for CPU exceptions. Those are events which are trigerred in the CPU itself, instead of receiving interrupt from the outside hardware. However, some CPU exceptions, such as NMI or #MC, directly relate to events happening in other components of the computer. Interrupt vectors 0x20 to 0xff (hexadecimal) are left free for developer's usage for external interrupts. Interrupts with numbers below 0x20 should not be assigned for external interrupts.
| Int. № | Mnem. | Type | Err. code | Name | Source | |
|---|---|---|---|---|---|---|
| hex | dec | |||||
| 0x00 | 0 | #DE | Fault | No | Divide Error | Integer divide instructions: DIV, IDIV and AAM. |
| 0x01 | 1 | #DB | Trap/Fault | No | Debug Exception | Instruction, data, and I/O breakpoints; single-step; INT1/ICEBP instruction and others. |
| 0x02 | 2 | NMI | Interrupt | No | NMI Interrupt | Nonmaskable external interrupt. |
| 0x03 | 3 | #BP | Trap | No | Breakpoint | INT3 instruction. |
| 0x04 | 4 | #OF | Trap | No | Overflow | INTO instruction. |
| 0x05 | 5 | #BR | Fault | No | BOUND Range Exceeded | BOUND instruction. Can also be generated by the Intel MPX instructions BNDCL,BNDCU,BNDCN,BNDLDX and BNDSTX. |
| 0x06 | 6 | #UD | Fault | No | Invalid Opcode (Undefined Opcode) | UD instruction or reserved opcode. |
| 0x07 | 7 | #NM | Fault | No | Device Not Available (No Math Coprocessor) | Any x87 instruction except WAIT/FWAIT when CR0.EM is set. Any x87 or SIMD (MMX/SSE/AVX/AVX-512/AMX) instruction except WAIT/FWAIT when CR0.TS is set. WAIT/FWAIT instruction when both CR0.TS and CR0.MP are set. |
| 0x08 | 8 | #DF | Abort | Yes (zero) | Double Fault | Any instruction that can generate an exception, an NMI, or an INTR. |
| 0x09 | 9 | #MP | Abort | No | Coprocessor Segment Overrun (reserved on 486 and later) | x87 floating-point instruction with a memory operand when middle part of memory operand is in inaccessible memory. (80287/80387 only; Intel 80486 and later processors will instead generate #GP or #PF exceptions for such operands) |
| 0x0A | 10 | #TS | Fault | Yes | Invalid TSS | Task switch or TSS access. |
| 0x0B | 11 | #NP | Fault | Yes | Segment Not Present | Loading segment registers or accessing system segments. |
| 0x0C | 12 | #SS | Fault | Yes | Stack-Segment Fault | Stack operations and SS register loads. |
| 0x0D | 13 | #GP | Fault | Yes | General Protection | Any memory reference and other protection checks. |
| 0x0E | 14 | #PF | Fault | Yes | Page Fault | Any memory reference. |
| 0x0F | 15 | —N/a | Intel reserved. Do not use. | |||
| 0x10 | 16 | #MF | Fault | No | x87 FPU Floating-Point Error (Math Fault) | x87 FPU floating-point, WAIT/FWAIT or MMX instruction. |
| 0x11 | 17 | #AC | Fault | Yes | Alignment Check | Misaligned memory access. On some newer processors, #AC can also be generated by instructions that try to perform locked accesses on uncacheable memory. |
| 0x12 | 18 | #MC | Abort/ Fault/ Interrupt | No | Machine Check | Hardware error. Error information is provided by machine-check MSRs. The set of errors that can be detected and reported through the Machine Check mechanism, as well as the MSRs that can hold the error information, are processor model dependent. |
| 0x13 | 19 | #XM | Fault | No | SIMD Floating-Point Exception | SSE/SSE2/SSE3/AVX/AVX2/AVX-512 floating-point instructions. |
| 0x14 | 20 | #VE | Fault | No | Virtualization Exception | EPT (Extended Page Table) violations (Intel VT-x guest only) |
| 0x15 | 21 | #CP | Fault | Yes | Control Protection Exception | When CET shadow stacks are enabled, the RET, IRET, RSTORSSP, and SETSSBSY instructions can generate this exception. When CET indirect branch tracking is enabled, this exception can be generated due to a missing ENDBRANCH instruction at the target of an indirect call or jump. |
| 0x16 ⋮ 0x1B | 22 ⋮ 27 | —N/a | Reserved for future use as CPU exception vectors. | |||
| 0x1C | 28 | #HV | Interrupt | No | Hypervisor Injection Exception | Event injection from hypervisor to SNP guest (AMD SEV-SNP guest only) |
| 0x1D | 29 | #VC | Fault | Yes | VMM Communication Exception | Virtual-machine exit events that require the VMM to inspect guest register state (AMD SEV-ES guest only) |
| 0x1E | 30 | #SX | Interrupt | Yes | Security Exception | Security-sensitive event (AMD SVM VMM only) |
| 0x1F | 31 | —N/a | Reserved for future use as CPU exception vector. | |||
| 0x20 ⋮ 0xFF | 32 ⋮ 255 | —N/a | Interrupt | No | —N/a | External interrupts. |
IBM PC layout
The IBM PC (BIOS and MS-DOS runtime) does not follow the official Intel layout beyond the first five exception vectors implemented in the original 8086. Interrupt 5 is already used for handling the Print Screen key, IRQ 0-7 is mapped to INT_NUM 0x08-0x0F, and BIOS is using most of the vectors in the 0x10-0x1F range as part of its API.
Hooking
Some Windows programs hook calls to the IDT. This involves writing a kernel mode driver that intercepts calls to the IDT and adds in its own processing. This has never been officially supported by Microsoft, but was not programmatically prevented on its operating systems until 64-bit versions of Windows, where a driver that attempts to use a kernel mode hook will cause the machine to bug check.
See also
General
External links
- (see CHAPTER 5, INTERRUPT AND EXCEPTION HANDLING and CHAPTER 10, ADVANCED PROGRAMMABLE INTERRUPT CONTROLLER)]
- at OSDev.org