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

int 10h模式13h下直接写入显存绘制像素失败求助

问题分析与解决方案

首先,你的代码存在两个关键问题导致绘制无效,我们逐一拆解解决:

1. 函数调用的参数入栈顺序完全颠倒

你的drawFaster过程定义的参数栈偏移是:

  • bp + 2:行(dx)
  • bp + 4:列(cx)
  • bp + 6:颜色

但实模式下的栈是先进后出的结构,参数入栈顺序必须和偏移定义相反——最后被push的参数会位于栈顶(对应bp+2)。你当前的调用代码入栈顺序完全搞反了:

push dx   ; 行,最先入栈 → 实际对应 bp+6
push cx   ; 列,中间入栈 → 实际对应 bp+4
push ax   ; 颜色,最后入栈 → 实际对应 bp+2

正确的入栈顺序应该是先push颜色,再push列,最后push行,这样栈顶的行参数才会匹配bp+2的定义:

push bp
mov ax, 30   ; 颜色
push ax
mov cx, 50   ; 列
push cx
mov dx, 50   ; 行
push dx
call drawFaster
pop bp

2. 内存操作的操作数大小不明确(导致[es:bx]无法运行的问题)

在16位汇编中,直接写mov [es:bx], 30时,汇编器会默认按**字(2字节)**处理操作,但VGA 13h模式下每个像素仅占1字节,这种字操作会覆盖相邻像素,甚至因操作数大小不匹配引发错误。

你看到mov [es:0], 30能“正常运行”,其实是汇编器把它解析为字操作,向显存起始地址写入了0x001E,相当于同时修改了第0和第1个像素,这并非正确的单像素绘制方式。正确写法需要显式指定字节操作:

mov ax, 0A000H
mov bx, 0
mov es, ax
mov byte ptr [es:bx], 30  ; 明确指定为字节操作

值得庆幸的是,你的drawFaster过程中mov [es:di], al是正确的——因为al是8位寄存器,汇编器会自动识别为字节操作,这部分无需修改。

额外验证建议

你可以先简化测试,在drawFaster里写死坐标和颜色:

drawFaster proc
pushad
mov ax, 0A000h
mov es, ax
mov di, 0  ; 固定屏幕左上角坐标
mov al, 30 ; 固定颜色
mov [es:di], al
popad
ret 6
endp

调用这个版本后,如果屏幕左上角出现对应颜色,说明显存地址和基础操作逻辑是正确的,再逐步恢复参数逻辑,能更高效地排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:05:25