我需要在程序集中使用代码在屏幕中间绘制一个正方形。
使用BIOS视频服务,屏幕分辨率应为320x200。尺寸的长度应为20像素。方块的颜色应为黄色,背景为黑色,如下所示:
答案 0 :(得分:4)
BIOS服务的开销极高,不应用于绘制单个像素。
对于“模式0x13”,您可以直接访问显示内存 - 每个像素1个字节,从0xA000:0x0000开始,其中每条水平线跟随前一条水平线(无间隙/填充)。例如:
mov ax,0xA0000
mov es,ax
xor di,di ;es:di = address of top left pixel
要填充屏幕的第一行,您需要将320字节(像素)设置为零。所以:
mov ax,0xA0000
mov es,ax
xor di,di ;es:di = address of top left pixel
xor ax,ax ;al = ah = black
mov cx,320/2 ;cx = number of pairs of pixels to set
cld ;Set direction to make sure
rep stosw ;Set entire line to black
现在,您需要将顶部设置的许多行设置为黑色,所以:
mov ax,0xA0000
mov es,ax
xor di,di ;es:di = address of top left pixel
;Do top lines
mov bx,(200-BOX_Y)/2 ;bx = number of lines at top to make black
xor ax,ax ;al = ah = black
.topLoop:
mov cx,320/2 ;cx = number of pairs of pixels to set
cld ;Set direction to make sure
rep stosw ;Set entire line to black
sub bx,1 ;bx = number of lines left to do
jne .topLoop ;Do next line if there are more lines to do
下一部分是盒子本身。对于框中的每一行,您需要左侧的一些黑色像素,中间的一些黄色像素和右侧的一些黑色像素:
;Do middle lines
mov bx,BOX_Y ;bx = number of lines in middle
.middleLoop:
mov cx,(320-BOX_X)/2 ;cx = number of pixels to set
rep stosb ;Set left black
mov cx,BOX_X
mov al,BOX_COLOUR ;al = box colour
rep stosb ;Set middle coloured part
mov cx,320-(320-BOX_X)/2 - BOX_X
xor al,al ;al = black
rep stosb ;Set right black part
sub bx,1 ;bx = number of lines left to do
jne .middleLoop ;Do next line if there are more lines to do
最后,您还要将底线设置为黑色。这就像做顶线。完整的代码就像这样:
mov ax,0xA0000
mov es,ax
xor di,di ;es:di = address of top left pixel
;Do top lines
mov bx,(200-BOX_Y)/2 ;bx = number of lines at top to make black
xor ax,ax ;al = ah = black
.topLoop:
mov cx,320/2 ;cx = number of pairs of pixels to set
cld ;Set direction to make sure
rep stosw ;Set entire line to black
sub bx,1 ;bx = number of lines left to do
jne .topLoop ;Do next line if there are more lines to do
;Do middle lines
mov bx,BOX_Y ;bx = number of lines in middle
.middleLoop:
mov cx,(320-BOX_X)/2 ;cx = number of pixels to set
rep stosb ;Set left black
mov cx,BOX_X
mov al,BOX_COLOUR ;al = box colour
rep stosb ;Set middle coloured part
mov cx,320-(320-BOX_X)/2 - BOX_X
xor al,al ;al = black
rep stosb ;Set right black part
sub bx,1 ;bx = number of lines left to do
jne .middleLoop ;Do next line if there are more lines to do
mov ax,0xA0000
mov es,ax
xor di,di ;es:di = address of top left pixel
;Do bottom lines
mov bx,200 - BOX_Y - (200-BOX_Y)/2
.bottomLoop:
mov cx,320/2 ;cx = number of pairs of pixels to set
rep stosw ;Set entire line to black
sub bx,1 ;bx = number of lines left to do
jne .bottomLoop ;Do next line if there are more lines to do
注意:上面的所有代码都是针对NASM的(不同的汇编程序可以不同);并且没有一个被测试过。我假设你处于真实模式。您需要定义一些常量才能使其工作(BOX_X
,BOX_Y
和BOX_COLOUR
)。在各种情况下可以更有效地完成。我没有打扰你正在使用的任何调用约定,或推送和弹出修改的寄存器,或执行ret
。我假设0x00是黑色的(并且太懒了,不能猜出黄色的值是多少);这可能是错误的(如何将值映射到颜色取决于您设置调色板的感觉,因此任何值都可以是任何颜色,0x00可能是亮粉色或其他任何颜色而不是黑色)