сборка носа: строка напечатана дважды - PullRequest
1 голос
/ 11 октября 2019

Я написал следующий код сборки x86 для ассемблера NASM.

hello.asm

[org 0x7c00]

mov bx, HELLO_MSG
call print_string

mov bx, GOODBYE_MSG
call print_string

jmp $

%include "print_string.asm"

HELLO_MSG:
    db 'hello, world',0

GOODBYE_MSG:
    db 'good bye',0

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

print_string.asm

print_string:
    mov ah, 0x0e
    push bx

    loop:
        cmp WORD [bx], 0
        je end
        mov al, [bx]
        int 0x10
        inc bx
        jmp loop

    end:
        pop bx
        ret

Я запустил код в эмуляторе bochs 2.2.6.

Ожидаемый выход

привет, мир, до свидания

вывод я получаю

привет, мир, до свидания, до свидания

Почему good bye печатается дважды? также обратите внимание, что после hello, world есть дополнительный пробел. Откуда это? NB. Если я печатаю только один строковый код, все работает отлично.

1 Ответ

3 голосов
/ 11 октября 2019

Ваша проблема исходит из строки

cmp WORD [bx], 0

Это говорит: "сравните слово по адресу, на который указывает bx, с 0."Однако строка, на которую вы смотрите, состоит из байтов, а не слов. Для того чтобы это сравнение было успешным, ему нужно было бы найти 2 байта подряд (иначе слово), которые оба содержат нули.

Это не происходит в конце HELLO_MSG, поэтому он просто продолжает печататьсимволы, идущие вправо через следующую строку (GOODBYE_MSG), пока, наконец, не найдет пару в times 510-($-$$) db 0.

Это также объясняет дополнительное пространство, которое вы видите, так как вы фактически печатаете 0 в концеHELLO_MSG.

...