Цвета текста ассемблера - PullRequest
4 голосов
/ 05 марта 2019

Я делаю 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

Ответы [ 2 ]

4 голосов
/ 11 марта 2019

В качестве предварительного совета всегда настраивайте регистры сегментов, от которых зависит ваш загрузчик.Здесь из-за 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
2 голосов
/ 06 марта 2019

Вы можете использовать Int 10 / AH: 0x09.Он имеет те же аргументы, что и Int 10 / AH: 0x0E, за исключением того, что BH - это цвет текста.Просто добавьте следующую строку в ваш код:

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

Еще одна альтернатива, которую я использую, поскольку функции BIOS недоступны в защищенном режиме.Используя память в 0x0B800.Общий код становится:

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

Дополнительные ресурсы для изучения могут включать:

...