Interrupts vs Exceptions

Low-level SWE interview prep — CPU signal handling, ISRs, and syscalls

In computer systems, interrupts and exceptions are like signals that tell the CPU to pause what it's doing and handle something important. They both temporarily stop a running program, but they are not the same — they come from different sources and are used for different reasons.

During normal execution, certain events may occur that cause the CPU to temporarily pause its current operations. These events are collectively known as exceptions. Among these, events initiated by external hardware (a keyboard press, a timer) are specifically classified as interrupts — an interrupt is actually one of the four classes of exceptions.

EXCEPTION (umbrella) INTERRUPT external, async e.g. keyboard, timer, disk I/O TRAP sync, intentional e.g. syscall, breakpoint FAULT sync, recoverable e.g. page fault, divide-by-zero ABORT sync, unrecoverable e.g. hardware / double fault
The four classes of exceptions. Interrupt is external + asynchronous; Trap, Fault and Abort are all internal + synchronous, but differ in intent and resumability.

Interrupt vs Exception — Timing

Interrupt (async, external) Exception (sync, internal)
CPU instruction stream: I1 I2 I3 (÷0) I4 I5 I6 I7 exception raised by THIS instruction external device signal — could land anywhere
An exception is tied to a specific instruction (synchronous). An interrupt arrives from outside the instruction stream and can land at any boundary (asynchronous).
Interrupt

Signal from external hardware

An interrupt is a signal sent to the processor by external hardware indicating that it needs immediate attention. Interrupts are asynchronous — they can occur at any time, regardless of what the processor is currently doing. The CPU pauses its current execution, saves state, and jumps to an Interrupt Service Routine (ISR).

Common sources:

After servicing, the processor resumes the previously running task exactly where it left off.

Exception

Event triggered by the CPU itself

An exception is triggered by something unusual or erroneous happening during instruction execution. Exceptions are synchronous — they occur precisely at the point a specific instruction causes an error or needs special handling.

Common causes:

The CPU invokes an exception handler that may terminate the program, retry the instruction, or perform corrective measures.

Trap, Fault & Abort — In Detail

These are the three synchronous sub-types of "exception." The key differentiator interviewers probe on is where execution resumes after the handler runs.

Trap

Synchronous, intentional — the program deliberately causes it, and it's not an error. Classic example: a system call (syscall on x86-64, int 0x80 legacy, svc on ARM). Also used for breakpoints (int3) and single-stepping in debuggers.

Resumes at the next instruction — the trapping instruction already did its job (e.g. syscall args were consumed).

Fault

Synchronous, potentially recoverable. Classic example: a page fault — the CPU accesses a virtual address not currently mapped (swapped out, copy-on-write, lazy allocation). The OS fixes the mapping and retries. Other example: general protection fault.

Resumes at the same instruction that faulted, so it can retry now that the condition is resolved.

Abort

Synchronous, unrecoverable. Severe hardware/system errors: uncorrectable ECC memory errors, bus errors, corrupted instruction fetches, or a double fault (a fault occurring while already handling another fault).

Does not resume — the process is terminated or the system halts/resets, since machine state may no longer be trustworthy.

Instruction stream with a faulting instruction at position X: I1 I2 X (event) I4 I5 TRAP resumes at NEXT instruction (I4) FAULT resumes at SAME instruction (X) — retried ABORT ✕ does not resume — process killed / system halted
Trap → next instruction. Fault → same instruction (retry). Abort → no resume.

Interrupt vs Exception — Full Comparison

FeatureInterruptException
DefinitionTriggered by external hardware to get CPU attention.Triggered by internal conditions or errors during instruction execution.
OriginExternal (outside the CPU).Internal (inside the CPU).
TimingAsynchronous — can occur at any time, unrelated to the current instruction.Synchronous — occurs during execution of a specific instruction.
PurposeHandle real-time external events (I/O devices).Handle errors or special conditions in program execution.
Handling RoutineInterrupt Service Routine (ISR).Exception Handler.
ExamplesKeyboard press, mouse click, printer request, timer signal.Divide by zero, illegal instruction, invalid memory access, system call.
MaskingCan often be enabled/disabled by the OS.Generally cannot be masked.
Control InterferenceConsidered normal; does not disrupt logical correctness.Usually abnormal; may terminate or crash the program.
Effect on Other EventsMay disable other hardware interrupts while processing.Does not generally disable other exceptions.
Instruction FlowMay interrupt the program at any point.Occurs exactly at the instruction causing it.

How Exception Handlers and Interrupt Handlers Differ

ISR
  • Invoked async, unrelated to what was executing
  • Identified by interrupt vector from controller (PIC/APIC)
  • Always resumes at interrupted point — instruction was unrelated
  • Reads device status/data registers for context
  • Can be masked (cli/sti on x86)
  • Priority-arbitrated by interrupt controller; can nest/preempt
Exception Handler
  • Invoked sync, direct result of current instruction
  • Identified by fixed exception vector (e.g. vector 0 = divide error, 14 = page fault)
  • Resume point depends on type: trap/fault/abort
  • Gets diagnostic data (e.g. faulting address in CR2, error code)
  • Generally cannot be masked
  • Nested faults escalate to double fault / abort, not graceful preemption

Interrupt Service Routines (ISRs) — In Detail

The ISR is the code the CPU jumps to when it receives an interrupt. Here's the full pipeline from hardware signal to resumed program.

1. Hardware side — getting the CPU's attention

Device (IRQ/MSI) Controller PIC / APIC / GIC CPU core save state, switch mode Vector lookup IDT / vector table ISR (top half) ack, query, clear deferred to bottom half (softirq / DPC)
Device → interrupt controller → CPU (save state + mode switch) → vector table lookup → ISR top half → deferred bottom-half work.

2. CPU's response when an interrupt arrives

  1. Finish current instruction cleanly — interrupts are instruction-boundary-clean, giving a well-defined return point.
  2. Save execution state — pushes RIP, RFLAGS, stack pointer onto the (often kernel) stack; may switch privilege level/stack via the Task State Segment on x86 so untrusted user code can't tamper with the handler.
  3. Look up the handler via vector number — indexes into the IDT (x86, 256 entries) or ARM's Vector Table.
  4. Jump to the ISR, switching to kernel/privileged mode.
  5. Mask interrupts during the transition to avoid reentrancy races.

3. What the ISR itself does — top half vs bottom half

A well-written ISR is kept short and fast, since other interrupts may be blocked while it runs. This is why OSes split handling into two halves:

Top half (the ISR)

Runs immediately, does the bare minimum: acknowledge at the controller (EOI), read status/data registers, clear the device's interrupt condition, and queue deferred work.

Bottom half (deferred)

Runs later with interrupts re-enabled: tasklets/softirqs/workqueues (Linux) or Deferred Procedure Calls (Windows) do the heavy lifting — e.g. copying a packet, waking a process.

  1. Acknowledge the interrupt at the controller (write EOI to the APIC) — otherwise it's still considered pending.
  2. Query the device (status/data register) to find out what happened and pull any immediately-needed data.
  3. Clear the device's interrupt condition so it stops asserting.
  4. Schedule deferred work if heavier processing is needed.
  5. Restore state and return via IRET (x86) / ERET (ARM) — restores flags and privilege/stack, unlike a normal ret.

4. Syscalls — the trap-flavored cousin

Syscalls reuse this same vectored machinery but as an intentional trap, not a hardware interrupt.

User mode (ring 3) Kernel entry Syscall table syscall / int 0x80 / svc (args in RAX,RDI,RSI…) dispatch by syscall number sys_read / sys_write / … sysret / iret / eret — resume at NEXT instr, return value in RAX
Syscall flow: user mode traps into the kernel, dispatches through the syscall table, executes the kernel function, then returns to the instruction right after the trap (trap-resumption semantics).

5. Why the split & masking matter

Interview payoff: keeping the top half tiny keeps interrupt latency low for other devices — a slow ISR delays every other equal/lower-priority interrupt (bad for audio, high-speed networking). Masking during the top half prevents reentrancy/races, which is also why ISRs can't take sleeping locks or block — there's no scheduler context to fall back to. Interrupt controllers support priority so higher-priority interrupts can preempt lower ones mid-service; nested faults, by contrast, escalate to a double fault/abort rather than gracefully preempting.
Terminology note: "Fault" in web-services/SOAP contexts (client apps catching SOAP faults) is unrelated to the CPU-architecture meaning above. In a low-level SWE interview, assume the OS/hardware definition unless told otherwise.