如何在DOS/BIOS/VGA的汇编中使背景始终为蓝色

问题描述 投票:0回答:1
.model small
.stack
.data
    num db 3
    msg1 db 13,10, 'Enter the size of the Square [1-9]: $'
         db 1Fh
    msg2 db 13,10, 'Do you want to try again? [y/n]: $'
         db 1Fh
    msg3 db 13,10, 'No Square to display. $'
         db 1Fh

.code
main    proc

    mov ax,@data
        mov ds,ax
        mov es,ax

        mov ah, 0
        mov al, 3

   get_input: int 10h

    mov ah, 6
        mov al, 0
    mov bh, 00010000b 
        mov cx, 0
        mov dx, 184FH
        int 10h
    
        mov ah, 09h
        mov dx, offset msg1
    int 21h

        mov ah, 01h
        int 21h 
        sub al, '0'    
        mov cl, al
        mov bx, 0

        cmp al, 0
        je no_square
        cmp al, 1
        je no_square

        mov ah, 02h
        mov dl, 0ah
        int 21h
        jmp outerloop_top

  no_square:
        mov ah, 09h
        mov dx, offset msg3  ; 'No Square to display' message
        int 21h
        jmp tryAgain

    outerloop_top:
        mov ch, cl
        mov bh, 1

    outerloop_rows:
        cmp bh, ch
        jg outerloop_exit
        mov bl, 1

        innerloop_columns:
            cmp bl, cl
            jg innerloopexit_top
            mov dl, '*'
            mov ah, 02h
            int 21h
            mov dl, ''
            mov ah, 02h
            int 21h
            inc bl
            jmp innerloop_columns

        innerloopexit_top:
        mov dl, 0dh
        mov ah, 02h
        int 21h
        mov dl, 0ah
        int 21h
        inc bh
        jmp outerloop_rows

    outerloop_exit:
        jmp tryAgain

    tryAgain:
        mov ah,09h
        mov dx, offset msg2 ; 'Do you want to try again? [y/n]:' message
        int 21h
        mov ah,01h
        int 21h
        cmp al, 59h

        je get_input
        cmp al, 79h
    
        je get_input
        jmp exit

    exit:
        mov ah,4ch
        int 21H
        int 20h

main    endp
end main

背景颜色保持蓝色的问题,因为经过几次重复后,它会变成黑色背景和白色前景。就像如果用户重复代码几次,它将返回到默认背景和前景。

我尝试在 YouTube 上关注一些内容,它使前景变成蓝色,背景变成黑色,并且出现了很多心形。 我希望每个显示器的背景都是蓝色的。

assembly background-color x86-16
1个回答
0
投票

先回顾一下

  mov ah, 0
  mov al, 3
get_input: int 10h  (1)

  ...

  cmp al, 59h
  je get_input
  cmp al, 79h
  je get_input
  jmp exit           (2)
exit:
  mov ah,4ch
  int 21H
  int 20h            (3)

(1)

int 10h
指令属于设置视频模式。您应该将其放置在 get_input 标签上方。目前幸运的是,当用户确认后代码跳转到get_input时,AH寄存器恰好保存了01h。这样唯一的危害就是愚蠢地要求按下一个键。
(2)
jmp exit
是多余的,因为无论如何执行都会在 exit 标签处继续。
(3)
int 20h
是多余的,因为它永远不会被执行。该程序已被 4Ch 函数终止。

滚动是罪魁祸首

每当 DOS 使屏幕滚动时,它都会再次使用默认的字符属性,即 WhiteOnBlack。使用可安装的控制台驱动程序(例如 ANSI.SYS),您可以让 DOS 使用其他一些设置。然后,您可以从命令行发出如下命令:

prompt $e[30;44m$p$g
。 理论上这是可行的,但实际上却不太有效!我经常目睹默认 WhiteOnBlack 属性的回归。总而言之,我早就放弃了 ANSI.SYS。
您的程序的解决方案很简单。只是永远不要允许滚动发生。每次用户确认要重试时,请将光标放在屏幕的左上角并从那里继续。或者,如果代码大小更短,您可以重置视频模式并再次将其涂成蓝色。

  mov  ax, 0003h
  int  10h          ; BIOS.SetVideoMode 3
get_input:
  xor  dx, dx
  mov  bh, 0
  mov  ah, 02h      ; BIOS.SetCursorPosition (0,0)
  int  10h

  mov ax, 0600h     ; BIOS.PaintRectangle (0,0)-(79,24)
  mov bh, 00010000b ; BlackOnBlue
  mov cx, 0
  mov dx, 184Fh
  int 10h

  ...

    
tryAgain:
  mov  ah, 09h
  mov  dx, offset msg2 ; 'Do you want to try again? [y/n]:' message
  int  21h
  mov  ah, 01h
  int  21h
  cmp  al, 'Y'
  je   get_input
  cmp  al, 'y'
  je   get_input
exit:
  mov  ah, 4C00h
  int  21H
© www.soinside.com 2019 - 2024. All rights reserved.