【问题标题】:8086 Assembly: wrong data reading video memory8086 组装:读取显存数据错误
【发布时间】:2014-11-04 00:33:46
【问题描述】:

我正在为一个用 8086 汇编语言编写的小游戏的学校项目工作。 我必须在屏幕上绘制(着色一些像素),为此我使用中断 10h 和模式 13h(ax = 13h)。这是一个 320 像素 X 200 像素的视频模式。

(注意:您最好阅读下面的文本,并在另一个选项卡中打开代码(您会更好地理解我用文字解释的内容)

首先初始化屏幕,这样我就可以确定每个像素都是黑色的。为此,我首先使用黑色 = 颜色编号 0 初始化调色板。

之后,我使用我编写的原始 for 循环过程来初始化屏幕(将每个像素设置为黑色)。我分别将起始索引(视频内存中的索引(即第一个像素为 0))、停止索引(64 000、最后一个像素(320px X 200px = 64 000))和索引的步长作为参数传递要递增。

所以它所做的只是在内存中从指定的开始地址循环到指定的停止地址,并且每个地址都将其设置为 0(因为黑色 = 调色板的颜色编号 0)。

所以通常现在我屏幕的每个像素都是黑色的。事实上,当我启动我的小程序时,会出现 320x200 视频模式并且屏幕是黑色的。

在程序的后面,我经常必须比较屏幕上像素的颜色。通常当我访问视频内存中的某个地址时,它必须是0(因为我将整个屏幕初始化为黑色(颜色编号 0)),除非我用另一种颜色为该像素着色。

但是在测试我的程序时,我发现 某些像素在屏幕上是黑色的(并且自初始化以来我从未改变它们的颜色)但是当我显示它们的值时,它似乎是 512 而不是 0。我不明白为什么,因为自从我初始化它们以来我从未改变过颜色。

我花了几个小时试图调试它,但我无法弄清楚为什么该像素突然从调色板的颜色编号 0(黑色)变为 512。

因为颜色值为 512 的像素在屏幕上也是黑色的,我想这也是该颜色的一个值,但我想明确使用颜色编号 0 表示黑色,以便我可以比较它(因为现在有 0 但也512 用于黑色和其他黑色值)。

相关部分代码:

mov ax, 0a000h ; begin address of video memory
mov es, ax
mov ax, [bp+4][0] ; We put the 1st argument (index) in register ax

mov di, ax
;;;; FOR DEBUGGING PURPOSES
mov ax, es:[di]
push ax ; We print the color of the pixel we are checking (normally has to be 0 if that pixel is black on the screen)
call tprint ; 70% of the time the printed color number is 0 but sometimes it prints color number 512 (also a black color but I don't want that, I initialized it to 0!!)
;;;; END DEBUG
;;;; ALSO STRANGE IS THAT WHEN I OUTCOMMENT THESE 3 LINES ABOVE, THE LAST PIXEL OF THE FIRST ROW IS COLORED
;;;; WHEN I LEAVE THESE 3 LINES LIKE NOW (PRINTING THE VALUE OF THAT PIXEL) IT IS THE NEXT PIXEL THAT IS COLORED
;;;; (strange but i don't really care since it was introduced only to debug)

CMP es:[di], 0 ; Comparison to see if the pixel we are checking is black.
; But when it is 512, my program will think it isn't the black color, and will stop executing (because after this call I do a JNZ jump to quit the loop)

感谢您的帮助!

【问题讨论】:

  • 您不能在模式 13h (320x200x8bit) 下使用颜色 512,因为每个像素只使用一个字节,因此无符号值的范围是 0 到 255。不经过您的代码,我假设您将零值从内存加载到低 8 位寄存器(alblcldl)并在相应的高 8 位寄存器(ahbh)中具有值 2 , ch, dh) 然后在相应的 16 位寄存器中(ax, bx, cxdx)你自然有 512 (2*256+0)。
  • 你为什么要删除你的代码?没有它,这个问题及其答案对网站的价值就会降低!

标签: memory assembly x86-16


【解决方案1】:

正如@nrz 暗示的那样,问题在于数据大小,尽管与他描述的略有不同。实际上,您正在加载 2 个字节,因此一次加载 2 个像素而不是 1。如果颜色为 0 的像素位于颜色为 2 的像素旁边,则会得到值 512。

您需要将第 182 行更改为 movzx ax, byte ptr es:[di],将第 190 行更改为 cmp byte ptr es:[di], 0(使用您的汇编程序支持的任何语法进行字节操作)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多