我正在为一个以8086汇编语言编程的小游戏的学校项目工作。 我必须在屏幕上绘制(颜色一些像素),这样做我使用中断10h模式13h(ax = 13h)。这是一个320px X 200px视频模式。
(注意:你最好用另一个标签打开的代码阅读下面的文字(你会更好地理解我用文字解释的内容))
我想首先初始化屏幕,所以我确定每个像素都是黑色。为此,我首先使用black = color number 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)
感谢您的帮助!
答案 0 :(得分:0)
正如@nrz暗示的那样,问题在于数据大小,尽管与他描述的略有不同。实际上你正在加载2个字节,所以一次加2个像素而不是1.如果颜色为0的像素位于颜色为2的像素旁边,则得到512的值。
您需要将第182行更改为movzx ax, byte ptr es:[di]
,将第190行更改为cmp byte ptr es:[di], 0
(使用汇编程序支持的任何语法进行字节操作)。