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

8086汇编:如何自定义中断服务程序(ISR)?含中断向量表疑问

8086汇编自定义中断服务程序(ISR)指南

先搞懂中断向量表(IVT)

8086的中断向量表是内存最开头1KB的区域(地址0000:0000到0000:03FF),相当于CPU的“中断地址目录”:

  • 每个中断号对应4字节的向量:前2字节是中断服务程序的偏移地址(IP),后2字节是段地址(CS)
  • 对于中断号n,它的向量起始地址是n×4,比如你提到的INT70(中断号70h,十六进制),向量地址是70h×4 = 1C0h:
    • 0000:01C0 ~ 0000:01C1 存储ISR的IP
    • 0000:01C2 ~ 0000:01C3 存储ISR的CS

自定义INT70的完整步骤

1. 编写中断服务程序(ISR)

ISR必须遵循固定规则:先保存用到的寄存器,执行自定义操作,最后用iret返回(不能用普通ret)。示例代码:

; INT70的中断服务程序
ISR_70:
    push ax          ; 保存寄存器,避免破坏主程序的寄存器状态
    push bx
    push dx

    ; 自定义操作:DOS下打印提示字符串
    mov ah, 09h      ; DOS功能调用:显示以$结尾的字符串
    mov dx, offset MSG
    int 21h

    pop dx           ; 恢复寄存器
    pop bx
    pop ax
    iret             ; 中断返回:自动弹出IP、CS、FLAGS,恢复现场

MSG db 'INT70 触发成功!$'  ; 要显示的消息,必须以$结尾

2. 修改中断向量表,注册你的ISR

要把ISR的CS和IP写入IVT对应位置,注意修改时要关中断(防止中途被其他中断打断):

; 设置INT70的中断向量
setup_int70:
    cli              ; 关中断,禁止其他中断干扰IVT修改
    mov ax, 0        ; IVT位于0段
    mov es, ax
    mov di, 70h * 4  ; 计算INT70的向量起始地址(70h×4=1C0h)

    mov ax, offset ISR_70  ; 取ISR的偏移地址(IP)
    stosw                  ; 写入IVT的前2字节(IP)
    mov ax, cs             ; 取ISR所在的段地址(CS)
    stosw                  ; 写入IVT的后2字节(CS)
    sti                    ; 开中断,恢复中断响应
    ret

3. 主程序调用自定义中断

在主程序中先完成中断向量注册,再调用INT70:

main:
    call setup_int70  ; 先注册INT70的中断向量
    int 70h           ; 调用自定义中断,执行ISR_70的代码
    mov ah, 4Ch       ; DOS功能调用:退出程序
    int 21h

关键注意事项

  • 寄存器保护:ISR必须保存所有它用到的寄存器(FLAGS除外),否则会破坏主程序的寄存器值,引发未知错误。
  • 用iret返回:iret会自动弹出栈中的IP、CS、FLAGS,完整恢复中断前的CPU状态,普通ret只弹出IP,无法正确收尾。
  • 关中断时机:修改IVT时必须用cli关中断,修改完成后用sti开中断,避免修改过程中CPU响应其他中断,读取不完整的向量地址。
  • 中断号选择:尽量选择DOS未占用的中断号(比如70h~77h通常保留给用户自定义),避免覆盖系统中断导致系统崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:55:14