The interrupt vector table (IVT) is an array of pointers, one per interrupt source, that maps each device’s identifying code to the address of the ISR that should handle it. With an IVT, the processor can jump directly to the right ISR on an interrupt — no polling required.

When a device asserts an interrupt, it sends a unique identifying code along with the IRQ signal. The processor uses that code as an index into the IVT, fetches the corresponding ISR address, and jumps there. The whole dispatch is one indexed memory read.

Without vectoring (polling-style ISR)

Without an IVT, the processor jumps to a single shared ISR address whenever any interrupt fires. The ISR has to figure out which device interrupted by reading each device’s STATUS register in turn:

GENERIC_ISR:
    LoadByte R4, KBD_STATUS
    And R4, R4, #IRQ_BIT
    Branch_if_NotZero R4, kbd_handler

    LoadByte R4, DISP_STATUS
    And R4, R4, #IRQ_BIT
    Branch_if_NotZero R4, disp_handler

    LoadByte R4, NET_STATUS
    ...

Slow if there are many devices: in the worst case the ISR polls every device before finding the culprit.

With vectoring (IVT)

Each device is assigned a unique vector number (an interrupt ID). When the device interrupts, it tells the processor “I’m device .” The processor:

  1. Looks up entry of the IVT.
  2. Jumps to the address stored there.

That address is the start of the device-specific ISR. No polling.

The IVT is just a table in memory:

IVT:
    .word kbd_isr      # vector 0: keyboard
    .word disp_isr     # vector 1: display
    .word net_isr      # vector 2: network
    .word disk_isr     # vector 3: disk
    ...

When a keyboard interrupt fires (vector 0), the processor reads IVT[0] = kbd_isr and jumps there directly.

Setup

The IVT is set up at boot time — typically by the OS kernel — with the addresses of all the device-specific ISRs. The OS may install or replace ISRs dynamically when drivers are loaded.

The base address of the IVT is held in a dedicated register (sometimes called the vector base register or interrupt base). The processor adds the vector number to this base to compute the table entry’s address.

Trade-offs

Pros of vectoring:

  • Fast interrupt dispatch — one indexed read instead of a poll loop.
  • Each device gets its own ISR — easier to manage in software.
  • Scales well to many devices — adding more doesn’t slow down dispatch.

Cons:

  • Requires hardware support for sending vector codes from devices to the processor.
  • More complex setup at boot time.
  • Need a fixed mapping of device → vector number — coordination problem if multiple drivers compete for vectors.

Modern processors (and microcontrollers) almost universally support vectored interrupts. Some, like ARM’s Cortex-M, have it built deeply into the architecture: the processor itself handles dispatch with no software intervention. The location of the table is relocatable via the VTOR (Vector Table Offset Register) — the OS or bootloader writes VTOR to point at the table it cares about. Cortex-M only defaults to address on reset; afterwards, the table can live anywhere in memory.

Variations

Priority is usually layered on top: each vector has a priority level, and a higher-priority interrupt can preempt a lower-priority ISR. Determining priorities can be hard-wired (lower vector numbers higher priority) or configurable.

Shared vectors are also common — when multiple low-bandwidth devices share an IRQ to save vector slots. The shared ISR then polls just the few devices on that line, which is still much faster than polling all devices.