assembly 更改字符串的背景色

ki1q1bka  于 2023-08-06  发布在  其他
关注(0)|答案(3)|浏览(112)

我在NASM有问题。我想改变背景颜色,但只为一个字符串。
以下是我的宏:

%macro SetBackGroundColour 0
    mov dx, 0
    mov bh, 0
    mov ah, 0x2
    int 0x10
    mov cx, 2000 
    mov bh, 0
    mov bl, 0x21 
    mov al, 0x20 
    mov ah, 0x9
    int 0x10     
%endmacro

%macro printOnTheScreen 1
    xor dx,dx 
    mov ah, 09h 
    mov dx, %1 
    int 21h 
    xor dx, dx
%endmacro

字符串
我尝试了其他的改变,但没有任何效果。

ghg1uchk

ghg1uchk1#

接下来是NASM中的一个过程,用颜色显示字符串,注意参数是如何在CALL之前设置的:

SECTION .data

text:  db  "Just some text"  ;LENGTH = 14.
color: db 181          
x:     db 0
y:     db 0

SECTION .text

global main
main:

  mov  bp, text ;STRING TO DISPLAY.
  mov  cx, 14          ;STRING LENGTH.
  mov  [x], byte 50    
  mov  [y], byte 20
  call color_string

;FINISH PROGRAM.
  mov  ax,4c00h
  int  21h

;----------------------------------------------     
;PARAMETERS : BP = OFFSET OF STRING TO DISPLAY.  
;             CX = STRING LENGTH.
;             COLOR = VARIABLE WITH COLOR (0..255).
;             X,Y   = VARIABLES WITH COORDINATES.

color_string:

  mov  ax, ds
  mov  es, ax         ;ES SEGMENT MUST POINT TO DATA SEGMENT.
  mov  ah, 13h        ;SERVICE TO DISPLAY STRING WITH COLOR.
  mov  bh, 0          ;PAGE (ALWAYS ZERO).
  mov  bl, color
  mov  dl, x          ;X (SCREEN COORDINATE). 
  mov  dh, y          ;Y (SCREEN COORDINATE). 
  int  10h           ;BIOS SCREEN SERVICES.  

  ret

字符串
设置光标位置的代码如下:

mov  ah, 2  ;SERVICE TO SET CURSOR POSITION.
mov  bh, 0  ;PAGE NUMBER (ALWAYS ZERO).
mov  dl, x  ;X COORDINATE 0..79.
mov  dh, y  ;Y COORDINATE 0..24.
int  10h    ;BIOS VIDEO SERVICES.

wqnecbli

wqnecbli2#

如果你通过DOS输出(你使用的是DOS.PrintString函数09h),你就失去了产生颜色的能力。幸运的是,BIOS确实支持彩色文本。阅读有关Displaying characters with DOS or BIOS中可用的DOS和BIOS文本输出功能的所有信息。
对于文本视频模式,您可以使用 WriteStringWithAttributeTVM 代码,该代码期望DS:SI指向以零结尾的文本,BL包含要使用的属性(在低半字节中指定前景色,在高半字节中指定背景色)。就像DOS.PrintString函数09h一样,它将展开制表符

; IN (bl,ds:si) OUT ()
WriteStringWithAttributeTVM:
      pusha
      mov     bh, 0           ; Display page 0
      jmp     .d
.a:   cmp     al, 9
      je      .Tab
      cmp     al, 13
      ja      .b
      mov     cx, 1101_1010_0111_1111b
      bt      cx, ax
      jnc     .c              ; {7,8,10,13} don't need the color
.b:   mov     cx, 1
      mov     ah, 09h         ; BIOS.WriteCharacterAndAttribute
      int     10h
.c:   mov     ah, 0Eh         ; BIOS.Teletype
      int     10h
.d:   lodsb
      test    al, al
      jnz     .a
      popa
      ret
.Tab: mov     cx, 1           ; Start displaying colored space(s)
      mov     ax, 0920h       ; BIOS.WriteCharacterAndAttribute
      int     10h
      mov     ah, 0Eh         ; BIOS.Teletype
      int     10h
      mov     ah, 03h         ; BIOS.GetCursor
      int     10h             ; -> CX DX
      test    dl, 7
      jnz     .Tab            ; Column not yet multiple of 8
      jmp     .d

字符串
有一个额外的BIOS函数,* 可以 * 显示一个字符串的颜色,但它不会展开标签像DOS.PrintString函数09h一样。这也是另一个答案中的解决方案,但在那里它包含一个错误。另一个缺点是,您需要事先知道字符串的长度,并且它需要奇怪的ES:BP指针。它唯一的好处是,你可以在调用中指定列和行。

; IN (bl,cx,dx,bp) OUT ()
;  BL Attribute eg. 1Fh is BrightWhiteOnBlue
;  CX Length of the string
;  DL Column
;  DH Row
;  BP Offset address of the string
WriteString:
      push    ax
      push    bx
      push    es
      mov     ax, ds          ; DS:BP --> ES:BP
      mov     es, ax
      mov     bh, 0           ; Display page 0
      mov     ax, 1301h       ; BIOS.WriteString
      int     10h
      pop     es
      pop     bx      
      pop     ax
      ret


关于mov ax, 1301h:因为AL中的WriteMode被设置为1,所以属性从BL寄存器中取出,并且游标被更新(就像DOS.PrintString函数09h所做的那样)。

5n0oy7gb

5n0oy7gb3#

您可以显示该字符串,并更改颜色,显示另一个字符串。例如下面的代码将背景色改为蓝色,前景色改为白色,然后将背景色改为黑色,前景色改为白色:

mov cx, 2000 
    mov bh, 0
    mov bl, 0x1F 
    mov al, 0x20
    mov ah, 0x9
    int 0x10

    ;display string here

    mov cx, 2000 
    mov bh, 0
    mov bl, 0x0F 
    mov al, 0x20
    mov ah, 0x9
    int 0x10

    ;display string here

字符串
注意:该代码在开始时没有清除屏幕。

相关问题