声明标签影响输出的位置

pen*_*048 3 x86 assembly nasm

我写了一个汇编程序来打印一个字符串:

[org 0x7c00]

mov bx, HELLO_MSG

HELLO_MSG:
db "Hello World!", 0

mov ah, 0x0e

PRINT:
mov al, [bx]
cmp al, 0
je END
int 0x10
add bx, 0x1
jmp PRINT

END:

jmp $
times 510-($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)

当使用nasm编译时,它生成了以下二进制文件

BB 12 7C B4 0E 8A 07 3C 00 74 07 CD 10 83 C3 01 EB F3 48 65 6C 6C 6C 6F 20 57 6F 72 6C 64 21 00 EB FE 00 00 .... 00 00 55 AA
Run Code Online (Sandbox Code Playgroud)

使用qemu仿真器的输出是

很明显,

很明显,"ll"被其他符号取代.

但是,如果我将HELLO_MSG标签移动到正上方jmp $的代码底部,则输出是正确的.我无法理解这背后的原因.

编辑:我在原始代码中尝试使用不同的字符串代替"Hello World"时观察到以下输出

案例: "Hellllo World"(通知额外'l')

垃圾信件只出现在这两个字节上

垃圾信件只出现在这两个字节上

案例: "我们是众神"

奇怪的是错误消失了!

奇怪的是错误消失了!

案例: "我们是众神!" (注意 '!')

没有打印,添加'!'  做了什么可怕的事情?

没有打印,添加'!' 做了什么可怕的事情?

案例: "Hello World"(通知!'!')

删除'!'  再次做了一件可怕的事情?

删除'!' 再次做了一件可怕的事情?

int*_*jay 5

您将字符串放在可执行代码的中间.所以ASCII值被视为指令操作码并执行一些操作,这可能会覆盖一些字节.

您应该在jmp指令之后将字符串放在末尾,以便不执行它.或者,您可以jmp在字符串之前添加指令以跳过它.