Вывод строки на ассемблере через int 10h

Пытаюсь вывести строку с помощью прерывания int 10h,но вместо нормального текста выводится разноцветная мишура из символов и раздается звук из наушников(долгое пищание),поправьте пожалуйста код.

;ustanovit cursor
mov ah,02h
mov dh,1
mov dl,1
int 10h
;vivesti stroku
mov ES:BP,offset msg
mov ah, 13h
mov cx,4
int 10h
msg db 'HAHA'
ret

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

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

(Предположу, что вы используете MASM или TASM)

Чтобы вывести строку через int 10h / mov ah, 13h нужно указать целый ряд регистров, а не только es, bp и cx

(Покажу на примере EXE программы DOS, не могу проверить на COM программу, но там чуть-чуть подкорректировать код надо просто)

.model small
.stack 100h

.data
    msg db 'HAHA' ; Сама строка

.code
main proc
    mov ax, @data ; Копируем сегмент данных
    mov ds, ax ; Копируем сегмент данных в ds
    mov es, ax ; Также копируем сегмент данных в es

    mov ah, 13h ; Функция `10h` прерывания BIOS

    ; Это флаг: если 1, использовать атрибут текста из регистра BL
    ; Это означает что цвет fg и bg будет браться из регистра BL
    ; Если бы регистр был равен 0, то нужно в самой строке после
    ; каждого символа писать атрибут
    mov al, 01h

    mov bh, 0 ; Видеостраница

    ; Атрибут текста, если первый бит al был нулём, то не используется
    ; А сам атрибут текста нужно писать по формату:
    ; 1-ая шестнадцатеричная цифра - цвет фона
    ; 2-ая шестнадцатеричная цифра - цвет текста
    ; Как вечная шпаргалка, какое значение за какой цвет отвечает можно
    ; открыть cmd в windows и ввести `color /?`
    ; В данном случае белый текст (7) на черном фоне (0)
    mov bl, 07h

    ; Длина строки в символах, если первый бит al равен 0,
    ; т.е. мы пишем после каждого символа его атрибут,
    ; то здесь мы будем писать именно количество символов,
    ; а не общее количество символов+атрибутов
    mov cx, 4

    ; BIOS игнорит позицию курсора, выставленную через `mov ah, 02h`
    ; Так что нужно в dh и dl выставить координаты
    ; Координаты начинаются с нуля
    mov dl, 0 ; Позиция X
    mov dh, 0 ; Позиция Y

    mov bp, offset msg ; Даём смещение на саму строку

    int 10h ; Вызываем прерывание
    
    ; ----- Делаем завершение программы (DOS)
    mov ah, 4Ch
    int 21h
main endp
end main
→ Ссылка