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.
The four classes of exceptions. Interrupt is external + asynchronous; Trap, Fault and Abort are all internal + synchronous, but differ in intent and resumability.
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:
Keyboard input
Mouse movements or clicks
Timer (clock) signals
Disk I/O completion
Network packet arrival
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:
Division by zero
Invalid or illegal instructions
Accessing memory outside the process (segmentation fault)
System calls from user programs
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.
Trap → next instruction. Fault → same instruction (retry). Abort → no resume.
Interrupt vs Exception — Full Comparison
Feature
Interrupt
Exception
Definition
Triggered by external hardware to get CPU attention.
Triggered by internal conditions or errors during instruction execution.
Origin
External (outside the CPU).
Internal (inside the CPU).
Timing
Asynchronous — can occur at any time, unrelated to the current instruction.
Synchronous — occurs during execution of a specific instruction.
Purpose
Handle real-time external events (I/O devices).
Handle errors or special conditions in program execution.
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
A device asserts an IRQ line, or sends a Message Signaled Interrupt (MSI/MSI-X) — a small memory write the chipset interprets as an interrupt.
These converge on an interrupt controller: legacy PIC (8259), modern APIC (local APIC per core + I/O APIC) on x86, or GIC on ARM.
The controller aggregates lines, applies priority/masking, and presents one vectored interrupt signal to a core.
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
Finish current instruction cleanly — interrupts are instruction-boundary-clean, giving a well-defined return point.
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.
Look up the handler via vector number — indexes into the IDT (x86, 256 entries) or ARM's Vector Table.
Jump to the ISR, switching to kernel/privileged mode.
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.
Acknowledge the interrupt at the controller (write EOI to the APIC) — otherwise it's still considered pending.
Query the device (status/data register) to find out what happened and pull any immediately-needed data.
Clear the device's interrupt condition so it stops asserting.
Schedule deferred work if heavier processing is needed.
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.
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).
User code sets registers per calling convention — Linux x86-64: syscall number in RAX, args in RDI, RSI, RDX, R10, R8, R9 — then executes a trap instruction:
syscall (x86-64 fast path via Model-Specific Registers, skips full IDT lookup)
int 0x80 (legacy 32-bit Linux, goes through the IDT — slower)
svc #imm (ARM/AArch64)
This causes a synchronous privilege switch from user mode (ring 3) to kernel mode (ring 0), landing at a fixed kernel entry point.
The kernel dispatcher reads the syscall number and indexes the system call table (e.g. sys_read, sys_write, sys_open).
The function runs in kernel mode, places a return value in RAX, and sysret/iret/eret drops back to user mode, resuming right after the syscall instruction.
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.