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

汇编程序重复打印字符串时随机丢失字符的原因排查

问题根因

该故障本质是实模式下显示模式切换后,BIOS显示子系统、DOS内核显示状态、显存残留数据三者不同步导致的,和message5字符串本身的内存存储无关,具体触发逻辑如下:

  • 你调用的int 10h ah=02h设置光标接口仅操作BIOS维护的光标位置变量,切换文本/图形模式后,如果没有强制重新初始化显示模式,BIOS记录的当前显示行列数、显存映射基址、光标硬件参数不会自动重置,和你实际使用的显示模式参数不匹配。
  • DOS的int 21h ah=09h字符串打印接口不会主动读BIOS的当前光标状态,而是维护自己的内部显示位置计数,同时会直接复用显存中对应位置的原有属性字节。你第二次打印时,显存里对应光标后一位(也就是字符'e'的打印位置)刚好残留了图形模式下写入的脏数据:要么属性字节是黑底黑字导致字符不可见,要么位置计算偏移把'e'写到了显存非显示区域,视觉上就呈现为字符缺失。
  • 低概率触发场景:模式切换过程中没有关中断,硬件中断触发的BIOS/DOS显示操作意外改写了对应显存位置的内容,刚好覆盖了'e'的写入结果。
排查步骤

按优先级从高到低操作:

  • 先排除字符串内存被篡改的可能
    第二次执行打印代码前,加一段遍历校验逻辑,从message5起始地址逐字节读取直到遇到'$'结束符,确认每个字节值依次为'h'、'e'、'l'、'l'、'o'、0ah、0dh、'$'。实模式下没有内存保护,业务逻辑的指针越界写很容易篡改看似不相关的内存,这步是排查的基础。
    校验参考代码:
    mov si, offset message5
    verify_str:
        lodsb
        cmp al, '$'
        jz verify_pass
        ; 可将al值输出到串口或直接写入显存临时区域,确认字节值正确
        jmp verify_str
    verify_pass:
    
  • 强制重置显示子系统状态
    模式切换完成后,不要直接执行打印逻辑,先调用BIOS接口重新初始化目标文本模式,清空显存残留、重置所有显示参数:
    mov ah, 00h
    mov al, 03h   ; 标准80*25 16色文本模式,根据你实际需求替换模式号
    int 10h
    
    重置后再执行原有打印逻辑,如果字符不再缺失,就可以确认是模式切换后状态未重置导致的故障。
  • 定位故障层级
    如果重置模式后问题仍然存在,替换打印接口做对照测试:逐字节读取message5的字符,调用int 10h ah=0eh(BIOS电传打字输出)打印完整字符串。如果BIOS接口打印无缺失,只有int 21h ah=09h打印丢字符,说明是DOS内核的显示状态向量在模式切换后被破坏,需要重新初始化DOS的显示相关PSP参数。
  • 校验光标位置与显存内容
    调用int 10h ah=02h设置光标后,立刻调用int 10h ah=03h(读光标位置,传入bh=0指定显示页0),确认返回的dh(行)、dl(列)值和你设置的21行、25列一致。如果读回值不对,说明BIOS的光标参数区在模式切换后未正确初始化。
    打印完成后直接读文本模式显存(段地址0B800h)对应位置的内容:文本模式下每个字符占2字节,低字节为ASCII值,高字节为显示属性,(21行,25列)对应的显存偏移为(21*80 + 25)*2。检查第二个字符(对应'e'的位置):
    • 若低字节值为0x65('e'的ASCII码)但屏幕不显示,说明高字节属性值为0(黑底黑字),是显存残留属性数据导致的视觉缺失;
    • 若低字节值不是0x65,说明存在其他代码(中断服务例程、后台业务逻辑)在打印过程中改写了该位置的显存,需要排查中断钩子和越界显存写逻辑。

内容的提问来源于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 10:18:30