Assembly Guide — Interrupts and Exceptions Handling
In this tutorial, you will learn about Assembly Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
x86-64 interrupts are events that transfer control to predefined handlers through the Interrupt Descriptor Table (IDT), handling hardware I/O, system calls, exceptions, and faults.
What You'll Learn
- Interrupt types: hardware, software, exceptions
- Interrupt Descriptor Table (IDT)
- INT instruction for system calls
- Exception Handling (page faults, division errors)
- Interrupt handler conventions
Why It Matters
Interrupts are the interface between software and hardware. Understanding them is essential for OS development, drivers, and system programming. Durga Antivirus Pro hooks interrupts for monitoring.
Real-World Use
Operating system kernels, device drivers, Embedded Systems, and security monitoring tools.
flowchart LR
A["Interrupts"] --> B["Types"]
B --> C["IDT"]
C --> D["Handlers"]
D --> E["System Calls"]
A:::current --> B
style A fill:#2563eb,stroke:#2563eb,color:#fff
style B fill:#dbeafe,stroke:#2563eb,color:#1e40af
style C fill:#dbeafe,stroke:#2563eb,color:#1e40af
style D fill:#dbeafe,stroke:#2563eb,color:#1e40af
style E fill:#f1f5f9,stroke:#94a3b8,color:#64748b
Interrupt Types
; Hardware interrupts (IRQs)
; Generated by hardware devices: keyboard, timer, disk
; Example: IRQ0 = timer, IRQ1 = keyboard
; Software interrupts (INT n)
; Generated by INT instruction
int 0x80 ; Linux syscall (legacy)
int 0x21 ; DOS syscall
; Exceptions
; Generated by CPU on errors:
; #DE (0): Division error
; #BP (3): Breakpoint
; #PF (14): Page fault
; #GP (13): General protection fault
INT Instruction
; Generate software interrupt
; Transfers control to interrupt handler
; In real mode / legacy:
mov ah, 0x09 ; Function number
mov dx, msg ; String pointer
int 0x21 ; DOS syscall
; Modern approach: SYSCALL instruction
; (not an interrupt, but same concept)
Interrupt Descriptor Table
; IDT: Array of 256 gate descriptors
; Each entry: 16 bytes (in 64-bit mode)
; Contains: handler address, segment selector, flags
; Structure (64-bit IDT entry):
; Bytes 0-1: Low 16 bits of handler offset
; Bytes 2-3: Code segment selector
; Bytes 4-5: Flags (type, DPL, present)
; Bytes 6-7: Middle 16 bits of handler offset
; Bytes 8-15: High 32 bits of handler offset
; IDT is loaded with LIDT instruction
lidt [idt_descriptor]
Simple Interrupt Handler
; Interrupt handler (save/restore registers)
section .text
global handler_timer
handler_timer:
; Save registers
push rax
push rcx
push rdx
push rsi
push rdi
push r8
push r9
push r10
push r11
; Handler body
; ... process interrupt ...
; Restore registers
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rcx
pop rax
; Return from interrupt
iretq
Exception Handling
; Division by zero (#DE, vector 0)
; CPU pushes error code (not for #DE)
; Handler must determine cause and respond
mov rax, 5
xor rbx, rbx ; divisor = 0
div rbx ; Triggers #DE exception
; Page fault (#PF, vector 14)
; CR2 contains the faulting address
; Error code provides access type info
handler_page_fault:
; CR2 has the faulting address
mov rax, cr2
; Error code on stack indicates:
; Bit 0: 0=non-present, 1=protection violation
; Bit 1: 0=read, 1=write
; Bit 2: 0=supervisor, 1=user
; ... handling ...
add rsp, 8 ; Remove error code
iretq
System Calls with INT 0x80
; Linux system calls (legacy 32-bit interface)
; Still works in 64-bit mode but uses different registers
section .data
msg db "Hello", 0xa
len equ $ - msg
section .text
; write(1, msg, len)
mov eax, 4 ; sys_write
mov ebx, 1 ; fd = stdout
mov ecx, msg ; buffer
mov edx, len ; length
int 0x80
; exit(0)
mov eax, 1 ; sys_exit
xor ebx, ebx ; code = 0
int 0x80
; Note: Prefer SYSCALL on modern 64-bit systems
Common Mistakes
1. Forgetting IRETQ
IRETQ returns from interrupt. RET is for regular functions. Using RET in handlers crashes the system.
2. Not saving registers
Interrupt handlers run in any context. Preserve all registers the handler modifies.
3. Masking interrupts for too long
STI enables, CLI disables interrupts. Keep interrupt-disabled sections short.
4. Stack overflow in handlers
Handler stacks are limited (typically 4KB on x86-64). Don't use deep Recursion.
5. RFLAGS corruption
Interrupts save RFLAGS automatically. But modifying IF inside handlers requires care.
Practice Questions
1. What is an interrupt vector? A number (0-255) identifying which interrupt handler to invoke, used as an index into the IDT.
2. How do interrupts differ from function calls? Interrupts save RFLAGS and can transition privilege levels. They use IRETQ to return. Function calls use RET.
3. What is the IDT? The Interrupt Descriptor Table holds addresses and attributes for all 256 interrupt handlers.
Challenge: Write a simple interrupt handler that counts the number of timer interrupts.
FAQ
{{< faq question="Can user-mode code handle interrupts?" >} No. Interrupt handlers run in kernel mode. User code cannot install or override handlers. {{< /faq >}}
{{< faq question="What is an interrupt gate vs trap gate?" >} Interrupt gates clear IF (disable interrupts). Trap gates don't. Use interrupt gates for hardware IRQs. {{< /faq >}}
{{< faq question="How many interrupts can x86-64 handle?" >} 256 total. 0-31 reserved for exceptions. 32-255 available for software and hardware interrupts. {{< /faq >}}
{{< faq question="What happens during an interrupt?" >} CPU saves RSP, SS, RFLAGS, CS, RIP, and error code on stack. Loads handler address from IDT. Jumps to handler. {{< /faq >}}
{{< faq question="Can interrupts be nested?" >} Yes. Higher-priority interrupts can interrupt lower-priority handlers. Each handler must re-enable interrupts when ready. {{< /faq >}}
Mini Project
Set up a simple interrupt handler (kernel code):
section .data
idt_ptr:
dw 256*16 - 1 ; Limit
dq idt ; Base address
section .bss
align 16
idt: resb 256*16 ; IDT table
section .text
global setup_idt
setup_idt:
; Fill IDT entries for handlers
; Each entry: 16 bytes
; ... setup code ...
lidt [idt_ptr]
sti ; Enable interrupts
ret
global timer_handler
timer_handler:
push rax
; Send EOI to PIC
mov al, 0x20
out 0x20, al
pop rax
iretq
What's Next
Now that you understand interrupts, explore Linux system calls for I/O operations.
| Topic | Description | Link |
|---|---|---|
| Assembly Syscalls | Linux system calls | {{< ref "13-syscalls" >}} |
| Assembly Strings | String operations | {{< ref "14-strings" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro