Сливаются строки при выводе с помощью int 10h

Проблема в том, что сливаются строки при выводе. Когда я вывожу какую-то из строк, в ней откуда-то появляются другие. В программировании на Windows достаточно было добавить нулевой символ в конец строки, но сейчас это не помогает.

P.S. Для отладки использую QEMU.

Код:

org 7c00h

start:
; очищаем всё что можно :)
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 07c00h
sti
; очищаем экран
mov ax, 3
int 10h
; скрытие курсора
mov ah, 1h
mov ch, 20h
int 10h
; установка позиции курсора
mov ah, 2h
xor bh, bh
mov dh, 0
mov dl, 0
int 10h
; вывод названия и версии ОС
mov ah, 13h
mov bp, ver
mov cx, 80
mov bl, 8Fh
int 10h
; устанавливаем курсор
mov ah, 2h
xor bh, bh
mov dh, 1
mov dl, 0
int 10h
; выводим сообщение о загрузке системы
mov ah, 13h
mov bp, info
mov cx, 80
mov bl, 91h
int 10h
; настройка параметров
mov ax, 0000h
mov es, ax
mov bx, 500h
mov ch, 0
mov cl, 02h
mov dh, 0
mov dl, 80h
mov al, 01h
mov ah, 02h
int 13h
; установка курсора
mov ah, 2h
xor bh, bh
mov dh, 2
mov dl, 0
int 10h
; выводим сообщение о готовности
mov ah, 13h
mov bp, info2
mov cx, 80
mov bl, 91h
int 10h

; данные
ver db "(worst)Bootloader for Qubit OS v1.0.",0
info db "INFO: Loading Qubit OS...",0
info2 db "INFO: All ready! Press Enter to boot into the system.",0


times(510-($-07C00h)) db 0 ; заполняем остальной сектор нулями
db 055h,0AAh


Ответы (1 шт):

Автор решения: insolor

При выводе строки в регистре cx вы передаете 80 - я предполагаю, что так вы указываете ширину экрана. На самом деле в cx нужно передавать фактическую длину выводимой строки, например для строки var нужно передавать 36.

Чтобы длину не высчитывать вручную, можно использовать такой трюк:

; Нулевые байты убрал, чтобы они не влияли на подсчет длины строки
; На вывод строк они никак не влияют
ver db "(worst)Bootloader for Qubit OS v1.0."
.len = $ - ver
info db "INFO: Loading Qubit OS..."
.len = $ - info
info2 db "INFO: All ready! Press Enter to boot into the system."
.len = $ - info2

Тогда для каждой строки в момент компиляции посчитается ее длина (текущий адрес $ минус адрес начала строки) и запишется как значение локальной метки .len. В коде используете длину так:

; вывод названия и версии ОС
mov ah, 13h
mov bp, ver
mov cx, ver.len
mov bl, 8Fh
int 10h

...

; выводим сообщение о загрузке системы
mov ah, 13h
mov bp, info
mov cx, info.len
mov bl, 91h
int 10h

...

; выводим сообщение о готовности
mov ah, 13h
mov bp, info2
mov cx, info2.len
mov bl, 91h
int 10h
→ Ссылка