В NASM этикетки рядом друг с другом в памяти вызывают проблемы с печатью

У меня проблема при программировании в NASM. Я учусь разрабатывать ОС исключительно в сборке и начал с создания загрузчика.

Моя цель в настоящее время - напечатать "Hello, World!" и "до свидания!" используя прерывание BIOS 0x10.

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

Почему нет hlen остановить цикл в конце первой строки?

    [org 0x7c00]

    mov ah, 0x0e

    mov bx, HELLO_MSG
    mov cx, hlen                                                                                                                                              
    call print_string

    mov bx, GOODBYE_MSG
    mov cx, glen                                                                                                                                              
    call print_string

    jmp $

    %include "print_string.asm"


    HELLO_MSG db 'Hello, World!',0
    GOODBYE_MSG db 'Goodbye!',0


    hlen equ $ - HELLO_MSG
    glen equ $ - GOODBYE_MSG

    times 510-($-$$) db 0
    dw 0xaa55

ОШИБКИ:

  1. Распечатывает прощальное сообщение дважды

    Это связано с печатью HELLO_MSG Hello, World! а также Goodbye!, Я считаю, что это происходит потому, что Hello_MSG ярлык находится рядом с GOODBYE_MSG метка в памяти

;;;print_string.asm
print_string:                   ;cx = string length                                                                                                                                                          
                                ;bX = string label - memory offset                                                                                                                       
                                ; -- if you want the data at a memory adress use [bx]                                                                                                                        
        mov al, [bx]
        int 0x10

        inc bx

        loop print_string

        ret

1 ответ

Решение

Ваше вычисление hlen включает в себя строку Goodbye! потому что это происходит после определения GOODBYE_MSG, Выражение $ - HELLO_MSG количество байтов между меткой HELLO_MSG и линия, где hlen определено. Вот почему ваш первый звонок print_string печатает оба сообщения.

Попробуйте этот порядок вместо:

HELLO_MSG db 'Hello, World!',0
hlen equ $ - HELLO_MSG

GOODBYE_MSG db 'Goodbye!',0
glen equ $ - GOODBYE_MSG
Другие вопросы по тегам