Assembly 影响输出的声明标签的位置

Assembly 影响输出的声明标签的位置,assembly,x86,nasm,Assembly,X86,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 使用nasm编译时,它生成以下二进制代码 BB 12 7C B4 0E 8A

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

[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
使用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
使用qemu仿真器的输出是

很明显,“ll”被其他符号取代

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

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

案例:“Helllo世界”(注意额外的“l”)

垃圾字母仅出现在这两个字节上

案例:“我们是神”

奇怪的是,错误消失了

案例:“我们是神!”(注意“!”)

未打印任何内容,添加“!”你做了什么可怕的事

案例:“你好,世界”(注意!)


删除“!”又做了什么可怕的事情?

你把字符串放在可执行代码的中间。因此,ASCII值被视为指令操作码并执行某些操作,这可能会覆盖某些字节

您应该将字符串放在
jmp
指令的末尾,这样它就不会被执行。或者,您可以在字符串之前添加
jmp
指令以跳过它