Assembly text colors

天涯浪子 提交于 2019-12-20 01:45:23

问题


I'm doing an iso file in assembly and I want to add color to the text (in this case: red).
Does anyone know how to do it?

[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

回答1:


As a preliminary advice, always setup the segment registers that your bootloader depends on. Here, because of lodsb together with [ORG 0x7C00], you must set DS=0.
Best also make sure the direction flag DF is in a known state. A simple cld will be enough.

To answer your question. The BIOS.Teletype function 0Eh that you use, can produce the desired red color but only while in a graphics video mode. Next solution will thus work:

[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

If however you want to work with the text video mode then BIOS.WriteCharacterWithAttribute function 09h is the right choice.

  • Pay attention because the parameters are different. BL now holds an attribute byte that specifies 2 colors at the same time (foreground in the low nibble and background in the high nibble) and an extra parameter uses the CX register.
  • Another point is that this function will show a colored glyph for every ASCII code. So the carriage return (13) and linefeed (10) will not get interpreted correctly unless you take measures.
  • The most important fact however is that this function does not advance the cursor. Luckily there's a neat trick. Just invoke both functions 09h and 0Eh in a row and voilà...

Example:

[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



回答2:


You can use Int 10/AH:0x09. It has the same arguments as Int 10/AH:0x0E, except that BH is the text color. Simply add the following line to your code.

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

Another alternative that I use, since BIOS functions, aren't available in protected mode. Using the memory at 0x0B800. The general code then becomes:

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

Additional resources for looking into this may include:

  • Editing Video Memory Directly.
  • Source code for Example OS using these methods.
  • Int 10h/AH:0x09


来源:https://stackoverflow.com/questions/55009353/assembly-text-colors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!