程序集 (x86): <label> db 'string',0 不会被执行,除非有跳转指令

Mic*_*ole 2 x86 assembly 16-bit bootloader

我一直在用头撞墙,试图理解为什么以下程序集没有正确转储“HELLO_WORLD”的内容。

; Explicitly set 16-bit
[ BITS 16 ]
[ ORG 0x7C00 ]

; Create label for hello world string terminated by null.
HELLO_WORLD db 'hello world', 0

start:
    ; Move address of HELLO_WORLD into si
    mov SI, HELLO_WORLD
    call print_string

    ; Continue until the end of time
    jmp $

print_string:
    loop:
        ; Retrieve value stored in address at si
        mov al, [SI]
        mov ah, 0x0E
        cmp al, 0
        ; Finish execution after hitting null terminator
        je  return
        INT 0x10
        ; Increment contents of si (address)
        inc SI
        jmp loop

    return:
        ret

; boot loader length *must* be 512 bytes.
times 510-($-$$) db 0
dw 0xAA55
Run Code Online (Sandbox Code Playgroud)

最后,我发现如果我们不执行(让它不编码)标签,那么它就可以正常运行。

jmp start
HELLO_WORLD db 'hello world',0    
Run Code Online (Sandbox Code Playgroud)

我发现最令人困惑的部分是,查看十六进制转储,HELLO_WORLD 仍在二进制文件中(在开头 - 似乎没有其类型的区别)。

猫 nojmp_boot.out

00000000  68 65 6c 6c 6f 20 77 6f  72 6c 64 00 be 00 7c e8  |hello world...|.|
00000010  02 00 eb fe 8a 04 b4 0e  3c 00 74 05 cd 10 46 eb  |........<.t...F.|
00000020  f3 c3 eb e8 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200
Run Code Online (Sandbox Code Playgroud)

猫 jmpboot.out

00000000  eb 22 68 65 6c 6c 6f 20  77 6f 72 6c 64 00 be 02  |."hello world...|
00000010  7c e8 02 00 eb fe 8a 04  b4 0e 3c 00 74 05 cd 10  ||.........<.t...|
00000020  46 eb f3 c3 eb e8 00 00  00 00 00 00 00 00 00 00  |F...............|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200
Run Code Online (Sandbox Code Playgroud)

检查前两个字节,我们可以看到 'e8 22' 是到地址 22 的短跳转(http://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf)。

我的问题是:

为什么我们不能将'HELLO_WORLD'作为程序执行的一部分,就我而言,代码和数据之间没有区别?

我正在使用以下内容进行编译:

nasm -f bin -o boot.bin boot.asm && if [ $(stat -c "%s" boot.bin) -ne 512 ]; then x; fi && qemu-system-x86_64 boot.bin
Run Code Online (Sandbox Code Playgroud)

Sep*_*and 5

执行从顶部开始。如果你省略了,jmp start那么字符h将被 CPU 解释为一条指令。你肯定看到这不可能是正确的吗?

就我而言,代码和数据之间没有区别吗?

当我们考虑它们在二进制文件中的位置时,代码和数据之间没有区别。但是代码和数据仍然是两个完全不同的项目。代码是唯一可以由 CPU执行的代码。