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

16位fasm汇编编写的vmem视频驱动.twritezs功能异常求助

代码问题排查结果

通用问题

  • 16位实模式下直接使用0xb8000作为32位基地址访问VGA显存不符合实模式寻址规则:实模式下物理地址计算公式为段地址*16 + 偏移地址,VGA文本缓冲区的正确访问方式是设置段寄存器为0xb800,用段+16位偏移访问,直接用32位地址0xb8000在16位汇编环境下会触发地址截断或非法寻址。
  • 所有涉及eax操作的偏移计算如果预期是32位运算,需要确认是否开启了地址大小前缀,16位模式下默认操作数/地址长度都是16位,直接用eax会生成额外前缀,部分环境下可能不兼容。

单函数BUG排查

1. .treadbyte 栈不平衡错误

函数开头push eax ebx仅压入2个寄存器,结尾pop eax ebx di多弹出了未压入的di,会导致栈帧被破坏,ret时读取错误的返回地址,直接触发程序跑飞。
修正方案:将结尾的pop改为pop ebx eax(栈为先进后出结构,弹出顺序要和压入顺序相反)。

2. .twritebyte 地址计算错误

函数内偏移计算时imul eax,2操作的是32位eax,后续inc ax仅修改eax的低16位,当传入的ID值大于32767时,高16位不会同步更新,导致地址计算错误。
修正方案:将inc ax改为inc eax。

3. .twritezs 多重错误(当前测试异常的核心原因)

  • 偏移计算逻辑被注释失效:注释了imul eax,2,传入的POS是字符序号(每个字符占2字节显存),当前直接add ebx, eax相当于把字符序号当作字节偏移使用,地址完全偏离预期。
  • 属性和字符写入顺序颠倒:VGA文本模式每个2字节单元的结构是[低字节:ASCII字符,高字节:属性],当前先把dl(属性)写入ebx,再把al(字符)写入ebx+1,顺序完全颠倒,会导致显示乱码/颜色异常。
  • 未保护si寄存器:lodsb会自动修改si的值,函数开头未压入si,结尾也未恢复,会破坏调用方的si寄存器上下文,导致外层逻辑异常。
  • 地址基址错误:同通用问题,16位模式下直接用0xb8000作为基址不合法。

修正后的.twritezs参考(实模式环境)

.twritezs:     ; in:eax=POS, [0 - 3440-len(ZS)]/si=ZS, offset[0 - 32512]/dl=BYTE; out:none
        push eax ebx si es
        mov bx, 0xb800
        mov es, bx
        imul eax, 2
        mov bx, ax
    .l:
        lodsb
        cmp al, 0x00
        je .ret
        mov byte es:[bx], al      ; 低字节写字符
        mov byte es:[bx+1], dl    ; 高字节写属性
        add bx, 2
        jmp .l
    .ret:
        pop es si ebx eax
        ret

内容的提问来源于stack exchange,提问作者Våñø Čhët

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:45:07