汇编(x86):< label> db' string',除非有SA跳转指令,否则不会执行0
我一直在墙上敲打头,以了解为什么以下组件没有正确地倾倒“ 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
最后,我发现,如果我们不执行(不是代码)标签,则它可以正常运行。
jmp start
HELLO_WORLD db 'hello world',0
我发现最令人困惑的部分,看着十六进制转储,Hello_world仍在二进制中(在开始时 - 似乎没有区别)。
cat 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
cat 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
检查前两个字节,我们可以看到'e8 22'是一个近亲,可以解决22(“ nofollow”>“ nofollow”> ion_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
I've been banging my head against the wall in an attempt to understand why the following assembly is not correctly dumping the contents of '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
In the end, I discovered that if we do not execute (make it not code) the label, then it functions correctly.
jmp start
HELLO_WORLD db 'hello world',0
The part I find the most confusing, looking at the hex dump, HELLO_WORLD is still in the binary (at the beginning - and there appears to be no distinction of its type).
cat 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
cat 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
Inspecting the first two bytes, we can see 'e8 22' is a shortjump to address 22 (http://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf).
My question is:
Why can we not have 'HELLO_WORLD' as a part of the execution of the program, as far I was concerned, there was no distinction between code and data?
I'm using the following for compilation:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
执行从顶部开始。如果您省略了
JMP启动
,则字符 h 将被CPU解释,就好像它是指令一样。当然,您认为这是不正确的吗?当我们考虑二进制中的放置时,代码和数据之间没有区别。但是代码和数据仍然保留2个完全不同的项目。代码是唯一可以由CPU执行的代码。
Execution starts at the top. If you omit the
jmp start
then the character h will get interpreted by the CPU as if it were an instruction. Surely you see that such can not be correct?There's no distinction between code and data when we consider their placement in the binary. But code and data still remain 2 completly different items. Code being the only one that can get executed by the CPU.
由于您正在创建引导扇区,因此执行始于生成文件的第一个字节。它不会从开始标签或其他任何地方开始。由于字符串“ Hello World”是在文件的开头,因此这些字节首先被执行。这些字节由CPU解释为说明,而不是字符,并且它们被执行为被解码为解码的任何说明。
以下是执行的说明:
Since you're creating a boot sector the execution begins at the first byte of the generated file. It won't begin at the start label or anywhere else. Since the string "hello world" is at the start of the file these bytes are what get executed first. These bytes are interpreted by the CPU as instructions, not characters, and they get executed as whatever instructions they get decoded as.
Here are the instructions that get executed: