assembly 组合文字颜色

os8fio9y  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(187)

我正在汇编中创建iso文件,并希望为文本添加颜色(在本例中为:红色)。
有人知道怎么做吗?

[BITS 16]
[ORG 0x7C00]

jmp main

main:
    mov si, string ; si=string
    call printstr
    jmp $

printstr:
    lodsb ; al=&si[0]
    cmp al,0 ;FLAGS = 0
    jnz print
    ret

print:
    mov  ah,0Eh
    int  10h
    jmp printstr

string db "HELLO WORLD!",13,10,0

times 510 - ($-$$) db 0
dw 0xAA55
xfb7svmp

xfb7svmp1#

作为初步建议,始终设置引导加载程序所依赖的段寄存器。在这里,由于lodsb[ORG 0x7C00]一起存在,因此必须设置DS=0
最好还要确保方向标志DF处于已知状态。简单的cld就足够了。
回答您的问题。您使用的BIOS.Teletype函数0Eh可以产生所需的红色**,但只能在图形视频模式下**。因此,下一个解决方案将起作用:

[BITS 16]
[ORG 7C00h]
    jmp     main
    ...
main:
    xor     ax, ax     ; DS=0
    mov     ds, ax
    cld                ; DF=0 because our LODSB requires it
    mov     ax, 0012h  ; Select 640x480 16-color graphics video mode
    int     10h
    mov     si, string
    mov     bl, 4      ; Red
    call    printstr
    jmp     $

printstr:
    mov     bh, 0     ; DisplayPage
print:
    lodsb
    cmp     al, 0
    je      done
    mov     ah, 0Eh   ; BIOS.Teletype
    int     10h
    jmp     print
done:
    ret

string db "HELLO WORLD!",13,10,0

times 510 - ($-$$) db 0
dw      0AA55h

然而,如果你想使用文本视频模式,那么BIOS.WriteCharacterWithAttribute函数09h是正确的选择。

  • 请注意,因为参数不同BL现在保存一个属性字节,该字节同时指定2种颜色(低半字节中的前景和高半字节中的背景),并且一个额外的参数使用CX寄存器。
  • 另一点是这个函数会为每个ASCII码显示一个彩色的字形,所以回车符(13)和换行符(10)将不能被正确解释,除非你采取措施。
  • 然而最重要的事实是这个函数并不能使光标前进。幸运的是有一个巧妙的技巧。只要连续调用函数09h和0Eh,瞧...

示例:

[BITS 16]
[ORG 7C00h]
    jmp     main
    ...
main:
    xor     ax, ax     ; DS=0
    mov     ds, ax
    cld                ; DF=0 because our LODSB requires it
    mov     ax, 0003h  ; Select 80x25 16-color text video mode
    int     10h
    mov     si, string
    mov     bl, 04h    ; RedOnBlack
    call    printstr
    jmp     $

printstr:
    mov     cx, 1     ; RepetitionCount
    mov     bh, 0     ; DisplayPage
print:
    lodsb
    cmp     al, 0
    je      done
    cmp     al, 32
    jb      skip
    mov     ah, 09h   ; BIOS.WriteCharacterWithAttribute
    int     10h
skip:
    mov     ah, 0Eh   ; BIOS.Teletype
    int     10h
    jmp     print
done:
    ret

string db "HELLO WORLD!",13,10,0

times 510 - ($-$$) db 0
dw      0AA55h
3hvapo4f

3hvapo4f2#

您可以使用Int 10/AH:0x 09。它与Int 10/AH:0x 0 E具有相同的参数,只是BH是文本颜色。只需在代码中添加以下行即可。

mov ah, 09h
mov bh, 0xF0     ; add this line, this is the text color (white on black)
int 10h

我使用的另一个替代方法,由于BIOS功能,在保护模式下不可用。使用0x 0 B800处的内存。通用代码则变为:

mov ebx, 0xb800      ; the address for video memeory
mov ah, 0xF0         ; the color byte is stored in the upper part of ax (ah).
printstr:
  lodsb              ; load char at si into al and increment si.
  cmp al, 0
  je .done
  mov [ebx], ax      ; move the character into video memeory.
  add ebx, 2         ; move the video memeory pointer up two bytes.
  jmp printstr
.done:
  ret

用于调查此问题的其他资源包括:

相关问题