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

替换INT 9 ISR时程序崩溃,但链式调用原ISR无异常

嘿,我懂你这种想彻底接管键盘中断的需求——那些常见示例都在链式调用原ISR、依赖BIOS的INT 16h服务,确实没法满足你的特殊场景。我来给你梳理下完全替换INT 9 ISR的核心要点和实现步骤:

核心实现步骤

1. 先存好原INT 9向量(可选但强烈建议)

虽然你不想链式调用原ISR,但提前保存它绝对是个好习惯——万一后续要恢复系统状态,或者调试时出问题能快速回滚。用这段代码获取并存储原向量:

mov ah, 35h
mov al, 09h
int 21h
; 原ISR的段地址存在es,偏移量在bx,把它们存到自定义变量里
mov [old_int9_offset], bx
mov [old_int9_segment], es

记得执行前用cli关中断,操作完再用sti开中断,避免向量被中途修改。

2. 安装你的自定义INT 9 ISR

接下来把你的中断处理程序挂到INT 9向量上,同样要先关中断防止竞态:

cli
mov ah, 25h
mov al, 09h
mov dx, offset my_custom_int9
push cs
pop ds ; 确保ds指向当前代码段,因为dx是程序内的偏移量
int 21h
sti

3. 自定义ISR的核心逻辑

你的ISR要直接和硬件打交道,完全绕开BIOS的处理流程,这里有几个必须做的事:

  • 读取60h端口获取键盘扫描码(通码是按键按下,断码是通码加80h,比如Esc键通码是01h,断码是81h)
  • 编写你自己的按键处理逻辑(比如判断扫描码执行对应操作)
  • 必须发送EOI(中断结束信号):向20h端口写入20h,告诉PIC中断已经处理完成,不然系统会一直收到键盘中断,直接死机!

示例代码大概是这样:

my_custom_int9:
    push ax bx cx dx ; 保存用到的寄存器,避免破坏上层程序状态
    in al, 60h ; 读取扫描码
    ; 这里写你的按键处理逻辑,比如判断扫描码执行对应操作
    mov al, 20h
    out 20h, al ; 发送EOI信号
    pop dx cx bx ax ; 恢复寄存器
    iret ; 中断返回

4. 必看的注意事项

  • 寄存器保护:ISR里用到的通用寄存器一定要push进去,处理完再pop出来,不然会打乱调用中断前的程序状态
  • ISR要尽量轻量化:别在里面做耗时操作,比如调用DOS的int 21h功能(除非是极简单的操作),不然会拖慢整个系统的响应
  • 退出前恢复原ISR:程序结束时一定要把之前保存的原INT 9向量恢复回去,不然其他程序或者系统本身会出现异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:23:38