Assembly text colors

前端 未结 2 506
栀梦
栀梦 2021-01-19 05:04

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 ma         


        
2条回答
  •  北荒
    北荒 (楼主)
    2021-01-19 05:37

    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
    

提交回复
热议问题