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