8086 Interrupts and System Calls
Master the interrupt system of 8086 microprocessor and learn to use DOS system calls for efficient programming.
Interrupt System Overview
Interrupts are signals that cause the processor to temporarily suspend its current program and execute a special routine called an Interrupt Service Routine (ISR).
Interrupt Types
- Type 0 (00H): Divide by zero error
- Type 1 (01H): Single step interrupt (trap flag)
- Type 2 (02H): Non-maskable interrupt (NMI)
- Type 3 (03H): One-byte interrupt (breakpoint)
- Type 4 (04H): Arithmetic overflow interrupt
- Type 5-31: Reserved by Intel
- Type 32-255: User-defined interrupts
Interrupt Vector Table
The Interrupt Vector Table (IVT) is located at memory addresses 00000H to 003FFH (first 1KB of memory). Each entry is 4 bytes long containing a far pointer (segment:offset).
Interrupt Processing Mechanism
When an interrupt occurs, the processor follows a specific sequence of actions to handle the interrupt.
Interrupt Processing Steps
- Interrupt Recognition: Processor identifies interrupt type
- Flag Preservation: Pushes flags register onto stack
- Disable Interrupts: Clears IF (Interrupt Flag) and TF (Trap Flag)
- Save Return Address: Pushes CS and IP onto stack
- Vector Calculation: Multiplies interrupt type by 4
- Load ISR Address: Loads new CS:IP from interrupt vector
- Execute ISR: Transfers control to interrupt service routine
- Return: IRET instruction restores registers and flags
Stack Frame During Interrupt
Before Interrupt: After INT Processing:
SP → [data] SP-6 → [Flags]
[data] SP-4 → [CS]
[data] SP-2 → [IP]
SP → [data]
[data]
Software Interrupts
Software interrupts are generated by the INT instruction and are commonly used to call system services.
INT Instruction Format
INT n ; Generate interrupt type n (0-255)
INT 21H ; DOS system calls
INT 10H ; BIOS video services
INT 16H ; BIOS keyboard services
INT 13H ; BIOS disk services
INTO ; Interrupt on overflow (if OF=1)
INT 3 ; One-byte breakpoint interrupt
Custom Interrupt Example
; Define custom interrupt service routine
.MODEL SMALL
.CODE
START:
; Install custom ISR for interrupt 60H
MOV AX, 3560H ; Get interrupt vector function
INT 21H ; ES:BX = current vector
MOV OLD_VECTOR_OFF, BX
MOV OLD_VECTOR_SEG, ES
; Set new vector
MOV AX, 2560H ; Set interrupt vector function
MOV DX, OFFSET MY_ISR
INT 21H
; Use custom interrupt
INT 60H ; Call our custom interrupt
; Restore original vector
MOV AX, 2560H
MOV DX, OLD_VECTOR_OFF
MOV DS, OLD_VECTOR_SEG
INT 21H
MOV AH, 4CH
INT 21H
MY_ISR PROC
; Custom interrupt service routine
PUSH AX
PUSH DX
MOV AH, 02H ; Display character
MOV DL, '*'
INT 21H
POP DX
POP AX
IRET ; Return from interrupt
MY_ISR ENDP
OLD_VECTOR_OFF DW ?
OLD_VECTOR_SEG DW ?
END START
DOS System Calls (INT 21H)
DOS provides a rich set of system services through interrupt 21H. The function number is specified in the AH register.
Common DOS Functions
; Character I/O
MOV AH, 01H ; Function 01H - Character input with echo
INT 21H ; Character returned in AL
MOV AH, 02H ; Function 02H - Character output
MOV DL, 'A' ; Character to display
INT 21H
MOV AH, 06H ; Function 06H - Direct console I/O
MOV DL, 0FFH ; Input mode
INT 21H ; Character in AL (no echo)
MOV AH, 07H ; Function 07H - Character input without echo
INT 21H
MOV AH, 08H ; Function 08H - Character input without echo
INT 21H
; String I/O
MOV AH, 09H ; Function 09H - Display string
MOV DX, OFFSET string ; DS:DX points to string
INT 21H
MOV AH, 0AH ; Function 0AH - Buffered string input
MOV DX, OFFSET buffer
INT 21H
File Operations
; Create file
MOV AH, 3CH ; Function 3CH - Create file
MOV CX, 0 ; File attributes
MOV DX, OFFSET filename
INT 21H ; Handle in AX
; Open file
MOV AH, 3DH ; Function 3DH - Open file
MOV AL, 2 ; Access mode (read/write)
MOV DX, OFFSET filename
INT 21H ; Handle in AX
; Read from file
MOV AH, 3FH ; Function 3FH - Read file
MOV BX, handle ; File handle
MOV CX, bytes_to_read
MOV DX, OFFSET buffer
INT 21H ; Bytes read in AX
; Write to file
MOV AH, 40H ; Function 40H - Write file
MOV BX, handle ; File handle
MOV CX, bytes_to_write
MOV DX, OFFSET data
INT 21H ; Bytes written in AX
; Close file
MOV AH, 3EH ; Function 3EH - Close file
MOV BX, handle ; File handle
INT 21H
; Delete file
MOV AH, 41H ; Function 41H - Delete file
MOV DX, OFFSET filename
INT 21H
Memory Management
; Allocate memory
MOV AH, 48H ; Function 48H - Allocate memory
MOV BX, paragraphs ; Number of paragraphs to allocate
INT 21H ; Segment address in AX
; Free memory
MOV AH, 49H ; Function 49H - Free memory
MOV ES, segment ; Segment to free
INT 21H
; Modify allocated memory
MOV AH, 4AH ; Function 4AH - Modify allocation
MOV BX, new_size ; New size in paragraphs
MOV ES, segment ; Segment to modify
INT 21H
BIOS Interrupts
BIOS (Basic Input/Output System) provides low-level hardware access through various interrupts.
Video Services (INT 10H)
; Set video mode
MOV AH, 00H ; Function 00H - Set video mode
MOV AL, 03H ; 80x25 color text mode
INT 10H
; Set cursor position
MOV AH, 02H ; Function 02H - Set cursor position
MOV BH, 0 ; Page number
MOV DH, 10 ; Row
MOV DL, 20 ; Column
INT 10H
; Display character at cursor
MOV AH, 0EH ; Function 0EH - Write character
MOV AL, 'A' ; Character to display
MOV BH, 0 ; Page number
INT 10H
; Scroll window up
MOV AH, 06H ; Function 06H - Scroll up
MOV AL, 0 ; Clear entire window
MOV BH, 07H ; Attribute (white on black)
MOV CX, 0 ; Upper left (0,0)
MOV DX, 184FH ; Lower right (24,79)
INT 10H
Keyboard Services (INT 16H)
; Read keystroke
MOV AH, 00H ; Function 00H - Read keystroke
INT 16H ; Scan code in AH, ASCII in AL
; Check if key available
MOV AH, 01H ; Function 01H - Check keystroke
INT 16H ; ZF=1 if no key available
; Get keyboard status
MOV AH, 02H ; Function 02H - Get shift status
INT 16H ; Status in AL
Disk Services (INT 13H)
; Reset disk system
MOV AH, 00H ; Function 00H - Reset disk
MOV DL, 80H ; Drive (80H = first hard disk)
INT 13H
; Read sectors
MOV AH, 02H ; Function 02H - Read sectors
MOV AL, 1 ; Number of sectors
MOV CH, 0 ; Cylinder
MOV CL, 1 ; Sector
MOV DH, 0 ; Head
MOV DL, 80H ; Drive
MOV BX, OFFSET buffer ; Buffer address
INT 13H
; Write sectors
MOV AH, 03H ; Function 03H - Write sectors
; Same parameters as read
INT 13H
; Get disk parameters
MOV AH, 08H ; Function 08H - Get drive parameters
MOV DL, 80H ; Drive
INT 13H ; Parameters returned in registers
Interrupt Programming Examples
Example 1: Custom Timer Interrupt
.MODEL SMALL
.DATA
counter DW 0
message DB 'Timer tick!', 0DH, 0AH, '$'
.CODE
START:
MOV AX, @DATA
MOV DS, AX
; Save original timer interrupt vector
MOV AX, 351CH ; Get interrupt vector for timer
INT 21H
MOV OLD_TIMER_OFF, BX
MOV OLD_TIMER_SEG, ES
; Install new timer handler
MOV AX, 251CH ; Set interrupt vector
MOV DX, OFFSET TIMER_HANDLER
INT 21H
; Wait for some timer ticks
MOV CX, 100
WAIT_LOOP:
HLT ; Wait for interrupt
LOOP WAIT_LOOP
; Restore original timer vector
MOV AX, 251CH
MOV DX, OLD_TIMER_OFF
MOV DS, OLD_TIMER_SEG
INT 21H
MOV AH, 4CH
INT 21H
TIMER_HANDLER PROC
PUSH AX
PUSH DX
PUSH DS
MOV AX, @DATA
MOV DS, AX
INC counter ; Increment tick counter
; Display message every 18 ticks (approximately 1 second)
CMP counter, 18
JNE TIMER_EXIT
MOV counter, 0 ; Reset counter
MOV AH, 09H
MOV DX, OFFSET message
INT 21H
TIMER_EXIT:
POP DS
POP DX
POP AX
; Chain to original handler
PUSHF
CALL FAR PTR [OLD_TIMER]
IRET
TIMER_HANDLER ENDP
OLD_TIMER_OFF DW ?
OLD_TIMER_SEG DW ?
END START
Example 2: Keyboard Hook
.MODEL SMALL
.DATA
key_count DW 0
status_msg DB 'Keys pressed: $'
.CODE
START:
MOV AX, @DATA
MOV DS, AX
; Install keyboard interrupt handler
MOV AX, 3509H ; Get INT 09H vector
INT 21H
MOV OLD_KB_OFF, BX
MOV OLD_KB_SEG, ES
MOV AX, 2509H ; Set INT 09H vector
MOV DX, OFFSET KB_HANDLER
INT 21H
; Main program loop
MAIN_LOOP:
MOV AH, 01H ; Check for keystroke
INT 16H
JZ MAIN_LOOP ; No key pressed
MOV AH, 00H ; Read keystroke
INT 16H
CMP AL, 27 ; ESC key
JE EXIT_PROG
; Display key count
CALL DISPLAY_COUNT
JMP MAIN_LOOP
EXIT_PROG:
; Restore original keyboard handler
MOV AX, 2509H
MOV DX, OLD_KB_OFF
MOV DS, OLD_KB_SEG
INT 21H
MOV AH, 4CH
INT 21H
KB_HANDLER PROC
PUSH AX
PUSH DS
MOV AX, @DATA
MOV DS, AX
INC key_count ; Count each key press
POP DS
POP AX
; Chain to original handler
PUSHF
CALL FAR PTR [OLD_KB]
IRET
KB_HANDLER ENDP
DISPLAY_COUNT PROC
MOV AH, 09H
MOV DX, OFFSET status_msg
INT 21H
MOV AX, key_count
CALL DISPLAY_NUMBER
MOV AH, 02H
MOV DL, 0DH
INT 21H
MOV DL, 0AH
INT 21H
RET
DISPLAY_COUNT ENDP
DISPLAY_NUMBER PROC
; Display number in AX as decimal
MOV BX, 10
MOV CX, 0
CONVERT_LOOP:
MOV DX, 0
DIV BX
PUSH DX
INC CX
CMP AX, 0
JNE CONVERT_LOOP
DISPLAY_DIGITS:
POP DX
ADD DL, '0'
MOV AH, 02H
INT 21H
LOOP DISPLAY_DIGITS
RET
DISPLAY_NUMBER ENDP
OLD_KB_OFF DW ?
OLD_KB_SEG DW ?
END START
Numerical Problems
Problem 1: Interrupt Vector Calculation
Question: Calculate the memory address of the interrupt vector for INT 25H.
Solution:
Interrupt vectors are stored at memory location 0000:0000
Each vector is 4 bytes long (2 bytes offset + 2 bytes segment)
Address = Interrupt Type × 4
= 25H × 4
= 94H
Memory locations:
0000:0094 - Offset (low byte)
0000:0095 - Offset (high byte)
0000:0096 - Segment (low byte)
0000:0097 - Segment (high byte)
Answer: Vector address = 0000:0094H
Problem 2: Stack Frame Analysis
Question: If SP = 1000H before an interrupt, what will be the stack contents after interrupt processing?
Solution:
Before interrupt: SP = 1000H
Interrupt processing pushes (in order):
1. Flags register (2 bytes)
2. CS register (2 bytes)
3. IP register (2 bytes)
After interrupt:
SP = 1000H - 6 = 0FFAH
Stack contents:
0FFAH: IP (low byte)
0FFBH: IP (high byte)
0FFCH: CS (low byte)
0FFDH: CS (high byte)
0FFEH: Flags (low byte)
0FFFH: Flags (high byte)
1000H: [original data]
Answer: SP = 0FFAH, 6 bytes pushed onto stack
Problem 3: ISR Execution Time
Question: Calculate the minimum overhead time for interrupt processing if each instruction takes 1 μs.
Solution:
Interrupt processing overhead includes:
1. Interrupt recognition: 1 μs
2. PUSHF (save flags): 1 μs
3. Clear IF and TF: 1 μs
4. PUSH CS: 1 μs
5. PUSH IP: 1 μs
6. Load new CS:IP: 2 μs
7. IRET instruction: 3 μs
- POP IP: 1 μs
- POP CS: 1 μs
- POPF: 1 μs
Total overhead = 1 + 1 + 1 + 1 + 1 + 2 + 3 = 10 μs
Answer: Minimum interrupt overhead = 10 μs
(Not including ISR execution time)
Interrupt Priority and Handling
Understanding interrupt priorities is crucial for system programming and real-time applications.
Interrupt Priority Order
- Divide Error (Type 0): Highest priority internal interrupt
- Debug Interrupt (Type 1): Single-step and breakpoint
- NMI (Type 2): Non-maskable external interrupt
- Breakpoint (Type 3): One-byte interrupt instruction
- Overflow (Type 4): INTO instruction when OF=1
- INTR: Maskable external interrupt
- Software Interrupts: INT n instructions
Nested Interrupt Handling
; Example of nested interrupt handling
ISR_LEVEL1 PROC
PUSH AX
PUSH BX
; Critical section - interrupts disabled
CLI ; Disable interrupts
; Critical code here
STI ; Re-enable interrupts
; Non-critical section - interrupts enabled
; Higher priority interrupts can occur here
POP BX
POP AX
IRET
ISR_LEVEL1 ENDP
ISR_LEVEL2 PROC
; Higher priority ISR
PUSH CX
PUSH DX
; Handle high priority interrupt
POP DX
POP CX
IRET
ISR_LEVEL2 ENDP
Real-Time Applications
Interrupts are essential for real-time applications where timely response to external events is critical.
Real-Time Clock Example
.MODEL SMALL
.DATA
hours DB 0
minutes DB 0
seconds DB 0
ticks DB 0 ; 18.2 ticks per second
.CODE
START:
; Install timer interrupt handler
MOV AX, 351CH
INT 21H
MOV OLD_TIMER_OFF, BX
MOV OLD_TIMER_SEG, ES
MOV AX, 251CH
MOV DX, OFFSET CLOCK_HANDLER
INT 21H
; Main program
MAIN_LOOP:
CALL DISPLAY_TIME
; Other program activities
JMP MAIN_LOOP
CLOCK_HANDLER PROC
PUSH AX
PUSH DS
MOV AX, @DATA
MOV DS, AX
INC ticks
CMP ticks, 18 ; Approximately 1 second
JL CLOCK_EXIT
MOV ticks, 0
INC seconds
CMP seconds, 60
JL CLOCK_EXIT
MOV seconds, 0
INC minutes
CMP minutes, 60
JL CLOCK_EXIT
MOV minutes, 0
INC hours
CMP hours, 24
JL CLOCK_EXIT
MOV hours, 0
CLOCK_EXIT:
POP DS
POP AX
; Chain to original timer
PUSHF
CALL FAR PTR [OLD_TIMER]
IRET
CLOCK_HANDLER ENDP
DISPLAY_TIME PROC
; Display current time in HH:MM:SS format
MOV AL, hours
CALL DISPLAY_BYTE
MOV AH, 02H
MOV DL, ':'
INT 21H
MOV AL, minutes
CALL DISPLAY_BYTE
MOV AH, 02H
MOV DL, ':'
INT 21H
MOV AL, seconds
CALL DISPLAY_BYTE
MOV AH, 02H
MOV DL, 0DH ; Carriage return
INT 21H
RET
DISPLAY_TIME ENDP
DISPLAY_BYTE PROC
; Display byte in AL as two decimal digits
MOV AH, 0
MOV BL, 10
DIV BL
ADD AL, '0'
MOV AH, 02H
MOV DL, AL
INT 21H
ADD AH, '0'
MOV DL, AH
MOV AH, 02H
INT 21H
RET
DISPLAY_BYTE ENDP
OLD_TIMER_OFF DW ?
OLD_TIMER_SEG DW ?
END START
Best Practices for Interrupt Programming
Effective interrupt programming requires following specific guidelines and best practices.
ISR Programming Rules
- Save and restore all registers: Use PUSH/POP for all modified registers
- Keep ISRs short: Minimize processing time in interrupt handlers
- Use IRET to return: Properly restore flags and return address
- Avoid DOS calls: Many DOS functions are not reentrant
- Handle reentrancy: Protect critical sections with CLI/STI
- Chain to original handlers: Preserve system functionality
Error Handling in ISRs
SAFE_ISR PROC
; Always save all registers used
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DS
PUSH ES
; Set up data segment
MOV AX, @DATA
MOV DS, AX
; Critical section - disable interrupts if needed
CLI
; Protected code here
STI
; ISR main functionality
; Keep this section as short as possible
; Error handling
CMP error_flag, 1
JNE ISR_EXIT
; Handle error condition
ISR_EXIT:
; Restore all registers in reverse order
POP ES
POP DS
POP DX
POP CX
POP BX
POP AX
IRET
SAFE_ISR ENDP