Assembly 绘制正方形的汇编代码

Assembly 绘制正方形的汇编代码,assembly,Assembly,我需要一个汇编代码在屏幕中间画一个正方形 使用BIOS视频服务,屏幕分辨率应为320x200。维度的长度应为20像素。正方形的颜色应为黄色,背景为黑色,如下所示:BIOS服务具有极高的开销,不应用于绘制单个像素 对于“模式0x13”,您可以直接访问显示内存-它是每像素1字节,从0xA000:0x0000开始,其中每个水平线跟随前一个水平线(无间隙/填充)。例如: mov ax,0xA0000 mov es,ax xor di,di ;es:di = a

我需要一个汇编代码在屏幕中间画一个正方形


使用BIOS视频服务,屏幕分辨率应为320x200。维度的长度应为20像素。正方形的颜色应为黄色,背景为黑色,如下所示:

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\u X
BOX\u Y
BOX\u color
)。在各种情况下都可以更有效地完成。无论您使用什么调用约定,或者推送和弹出修改过的寄存器,或者执行
ret
,我都不介意。我假设0x00是黑色的(并且懒得猜测黄色的值);这可能是错误的(值如何映射到颜色取决于您如何设置调色板,因此任何值都可以是任何颜色,0x00可能是亮粉色或其他任何颜色,而不是黑色)

该死的,这让我回过神来!我还有一本1000多页的EGA和VGA编程指南,在某处尘封。谢谢你的帮助。。。。。。。。竖起大拇指