装配文本颜色

Fla*_*lag 4 assembly colors bootloader x86-16

我正在汇编中创建一个 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
Run Code Online (Sandbox Code Playgroud)

Sep*_*and 5

作为初步建议,请始终设置引导加载程序所依赖的段寄存器。这里,因为lodsb与 一起[ORG 0x7C00],所以必须设置DS=0
\n最好还确保方向标志 DF 处于已知状态。一个简单的cld就足够了。

\n\n

来回答你的问题。您使用的 BIOS.Teletype 函数 0Eh 可以产生所需的红色,但仅在图形视频模式下有效。\n下一个解决方案将因此起作用:

\n\n
[BITS 16]\n[ORG 7C00h]\n    jmp     main\n    ...\nmain:\n    xor     ax, ax     ; DS=0\n    mov     ds, ax\n    cld                ; DF=0 because our LODSB requires it\n    mov     ax, 0012h  ; Select 640x480 16-color graphics video mode\n    int     10h\n    mov     si, string\n    mov     bl, 4      ; Red\n    call    printstr\n    jmp     $\n\nprintstr:\n    mov     bh, 0     ; DisplayPage\nprint:\n    lodsb\n    cmp     al, 0\n    je      done\n    mov     ah, 0Eh   ; BIOS.Teletype\n    int     10h\n    jmp     print\ndone:\n    ret\n\nstring db "HELLO WORLD!",13,10,0\n\ntimes 510 - ($-$$) db 0\ndw      0AA55h\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

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

例子:

\n\n
[BITS 16]\n[ORG 7C00h]\n    jmp     main\n    ...\nmain:\n    xor     ax, ax     ; DS=0\n    mov     ds, ax\n    cld                ; DF=0 because our LODSB requires it\n    mov     ax, 0003h  ; Select 80x25 16-color text video mode\n    int     10h\n    mov     si, string\n    mov     bl, 04h    ; RedOnBlack\n    call    printstr\n    jmp     $\n\nprintstr:\n    mov     cx, 1     ; RepetitionCount\n    mov     bh, 0     ; DisplayPage\nprint:\n    lodsb\n    cmp     al, 0\n    je      done\n    cmp     al, 32\n    jb      skip\n    mov     ah, 09h   ; BIOS.WriteCharacterWithAttribute\n    int     10h\nskip:\n    mov     ah, 0Eh   ; BIOS.Teletype\n    int     10h\n    jmp     print\ndone:\n    ret\n\nstring db "HELLO WORLD!",13,10,0\n\ntimes 510 - ($-$$) db 0\ndw      0AA55h\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我是赞成票,但我想提一下,如果您要使用字符串指令(LODSx/CMPSx/SCASx 等),您还需要确保根据需要设置方向标志(在此代码中转发将当然需要CLD)。BIOS 不保证方向标志被清除。附带说明:其中一个模拟器曾经有一个有趣的错误,如果您使用 STD 反转方向,则 Int 13h/Ah=2 磁盘读取失败 LOL。 (4认同)