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

汇编语言中如何清空键盘缓冲区解决按键响应延迟问题

问题解决方案

你判断的延迟原因完全准确:PC键盘长按时会触发自动重复输入,持续向BIOS键盘环形缓冲区(位于BIOS数据段,最多缓存15个按键事件)写入数据,你每次循环仅读取1个按键,剩余事件持续积压就会导致响应越来越慢。
没有专用中断可以直接一键清空键盘缓冲区,但有两种成熟的DOS实模式下清空缓冲区的实现方案,适配你当前的汇编代码:

方案1:循环读取丢弃所有待处理按键(兼容性最佳,推荐)

利用int 16h的两个功能组合实现:

  • AH=01h, int 16h:检测缓冲区是否有未读按键,ZF=0代表存在待读按键
  • AH=00h, int 16h:从缓冲区读取一个按键,直接丢弃即可
    循环执行上述逻辑直到缓冲区为空(ZF=1),不需要操作额外内存段,所有DOS兼容环境都可运行。

方案2:直接重置缓冲区指针(执行效率最高)

BIOS键盘缓冲区的头、尾指针存放在0040:001A和0040:001C两个内存地址,当两个指针值相等时,BIOS会判定缓冲区为空。直接将两个指针都设为缓冲区起始偏移1Eh即可瞬间清空缓冲区,不需要循环。

注意:修改指针时需要临时关中断,避免键盘中断在修改过程中写入新数据导致指针不一致。


适配你代码的修改示例

把原有key过程替换为如下实现(采用方案2,同时兼容你原有逻辑):

proc key
push bp
mov bp,sp
push ax
push bx
push cx
push si
push dx
push di
push es ; 新增保存段寄存器,用于访问BIOS数据段

    mov [hi],0
    ; 清空键盘缓冲区
    mov ax, 40h
    mov es, ax
    cli
    mov es:[1Ah], word ptr 1Eh
    mov es:[1Ch], word ptr 1Eh
    sti

    ; 原有按键检测逻辑
    mov ah, 01
    int 16h
    jz L3
    
    mov ah, 00h
    int 16h
    cmp al, 68h
    jne L3
    mov [hi],1

L3:
pop es ; 恢复段寄存器
pop di
pop dx
pop si 
pop cx
pop bx
pop ax
pop bp
ret 
endp key

额外优化建议

你现有代码每次主循环都切换一次13h图形模式、再切回2号文本模式,属于完全不必要的开销,会额外加重延迟。只需要在程序开头初始化时设置一次你需要的显示模式即可,不需要在循环里反复切换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:03:20