You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用TASM在8086中实现带优先级的PDP11风格硬件中断?

8086 TASM Interrupt Priority Implementation Example

Got it, let's walk through a complete, runnable TASM example that meets your requirements: a low-priority default execution routine, a higher-priority keyboard interrupt handler, and the highest-priority system clock interrupt handler. This uses standard 8086 interrupt mechanics and preserves compatibility with original BIOS routines.

Key Background

The 8086 hardware interrupt priority is fixed for IRQs:

  • IRQ0 (Clock, INT 08h) → Highest priority
  • IRQ1 (Keyboard, INT 09h) → Next highest
  • Main program (default routine) → Lowest priority (gets interrupted by any IRQ)

We'll replace the default INT 08h and INT 09h vectors with custom handlers, while saving the original vectors so we can chain back to BIOS functionality if needed.

Complete TASM Code

.MODEL SMALL
.STACK 100H

.DATA
    ; Strings for output
    DEFAULT_MSG DB 'Running default routine... $'
    CLOCK_MSG   DB 0Dh, 0Ah, 'Clock interrupt triggered (Highest priority)$'
    KEYBOARD_MSG DB 0Dh, 0Ah, 'Keyboard interrupt triggered (Medium priority)$'
    
    ; Variables to store original interrupt vectors
    OLD_INT08_OFF DW ?
    OLD_INT08_SEG DW ?
    OLD_INT09_OFF DW ?
    OLD_INT09_SEG DW ?

.CODE
MAIN PROC
    ; Initialize data segment
    MOV AX, @DATA
    MOV DS, AX

    ; Save original INT 08h (clock) vector
    MOV AH, 35h
    MOV AL, 08h
    INT 21h
    MOV OLD_INT08_OFF, BX
    MOV OLD_INT08_SEG, ES

    ; Save original INT 09h (keyboard) vector
    MOV AH, 35h
    MOV AL, 09h
    INT 21h
    MOV OLD_INT09_OFF, BX
    MOV OLD_INT09_SEG, ES

    ; Set custom INT 08h handler
    MOV AH, 25h
    MOV AL, 08h
    MOV DX, OFFSET CLOCK_HANDLER
    PUSH DS
    MOV DS, CS
    INT 21h
    POP DS

    ; Set custom INT 09h handler
    MOV AH, 25h
    MOV AL, 09h
    MOV DX, OFFSET KEYBOARD_HANDLER
    PUSH DS
    MOV DS, CS
    INT 21h
    POP DS

    ; Default execution routine (lowest priority)
DEFAULT_LOOP:
    ; Clear screen and print default message
    MOV AH, 0Fh
    INT 10h
    MOV AH, 00h
    INT 10h
    MOV AH, 09h
    LEA DX, DEFAULT_MSG
    INT 21h

    ; Wait a bit (simulate work)
    MOV CX, 0FFFFh
WAIT_LOOP:
    DEC CX
    JNZ WAIT_LOOP
    JMP DEFAULT_LOOP

    ; Restore original vectors (unreachable in this example, but good practice)
RESTORE_VECTORS:
    MOV AH, 25h
    MOV AL, 08h
    MOV DX, OLD_INT08_OFF
    MOV DS, OLD_INT08_SEG
    INT 21h

    MOV AH, 25h
    MOV AL, 09h
    MOV DX, OLD_INT09_OFF
    MOV DS, OLD_INT09_SEG
    INT 21h

    ; Exit program
    MOV AH, 4Ch
    INT 21h
MAIN ENDP

; Highest priority: Clock interrupt handler (INT 08h)
CLOCK_HANDLER PROC FAR
    ; Save registers to stack
    PUSH AX
    PUSH DX
    PUSH DS

    ; Set data segment
    MOV AX, @DATA
    MOV DS, AX

    ; Print clock interrupt message
    MOV AH, 09h
    LEA DX, CLOCK_MSG
    INT 21h

    ; Send EOI to PIC (must do to allow future interrupts)
    MOV AL, 20h
    OUT 20h, AL

    ; Call original BIOS clock routine (optional, keeps system time working)
    PUSH CS
    POP DS
    JMP DWORD PTR OLD_INT08_OFF

    ; Restore registers
    POP DS
    POP DX
    POP AX
    IRET
CLOCK_HANDLER ENDP

; Medium priority: Keyboard interrupt handler (INT 09h)
KEYBOARD_HANDLER PROC FAR
    ; Save registers
    PUSH AX
    PUSH DX
    PUSH DS

    ; Set data segment
    MOV AX, @DATA
    MOV DS, AX

    ; Read keyboard scan code
    IN AL, 60h

    ; Print keyboard interrupt message
    MOV AH, 09h
    LEA DX, KEYBOARD_MSG
    INT 21h

    ; Send EOI to PIC
    MOV AL, 20h
    OUT 20h, AL

    ; Call original BIOS keyboard routine (handles key echo, etc.)
    PUSH CS
    POP DS
    JMP DWORD PTR OLD_INT09_OFF

    ; Restore registers
    POP DS
    POP DX
    POP AX
    IRET
KEYBOARD_HANDLER ENDP

END MAIN

How to Compile & Run

  1. Assemble with TASM: tasm interrupt_priority.asm
  2. Link with TLINK: tlink interrupt_priority.obj
  3. Run the .exe file in an 8086 emulator (like DOSBox, Bochs, or VirtualBox with DOS)

Key Explanations

  • Interrupt Vector Management: We use INT 21h functions 35h (get vector) and 25h (set vector) to safely replace and restore interrupt handlers without breaking system functionality.
  • EOI Signal: After handling an interrupt, we send 20h to port 20h (PIC master) to tell the hardware we're done—this is critical to allow subsequent interrupts to fire.
  • Priority Behavior: The clock interrupt (IRQ0) will preempt the keyboard interrupt (IRQ1), and both will preempt the main default routine. You'll see the clock message appear even if the keyboard handler is mid-execution.
  • Chaining to BIOS: We call the original BIOS handlers to preserve core system features (like keeping the system clock updated and handling key input echo). You can remove these calls if you want full control over the interrupts.

内容的提问来源于stack exchange,提问作者Dean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:24:20