【发布时间】:2011-08-24 04:38:55
【问题描述】:
我正在创建自己的“玩具”操作系统,并且已经到了尝试理解链接和可执行格式的地步——特别是我有一个平面文件二进制格式可执行文件,我正在将其加载到内存中地址0x500,然后直接调用。例如,考虑以下两条指令(我知道这是人为的,我只想在我的示例中同时包含 call 和 mov)
mov ax, some_label
call some_label
; some_label is at address 0x99 into the resulting binary
到目前为止,我一直在使用 NASM 通过使用 org 0x500 指令和命令 nasm -f bin myfile.asm 来生成所需的输出。生成的反汇编看起来像这样并且完美运行:
mov ax, 0x599
call 0x599
我现在想开始使用 LD,以便我可以链接到其他对象,但经过大量实验和阅读后,我仍然不太了解发生了什么足以获得可靠的结果。
为了产生类似的输出,我收集了更多信息:
- 让 NASM 输出为 obj 格式,其中包括适合链接的符号信息(我选择了 ELF,因为它似乎是任何一种格式都一样好)
- 让 LD 将结果与
.text部分的地址链接为0x500,然后将结果作为平面二进制文件发出 - 它是链接器最终决定各种偏移在最终二进制文件中解析为什么.
到目前为止,我已经尝试了以下方法:
:: Output as ELF
nasm -f elf myfile.asm
:: Then link and output as binary with the address of .text as 0x500
ld --oformat binary -Ttext 0x500 myfile.o
但是这给了我以下错误(这是在 Mingw 上):
ld: 无法对非 PE 输出文件执行 PE 操作
谷歌搜索将我带到this mailing list,这似乎是有道理的,所以我尝试了以下方法:
:: Output as ELF
nasm -f elf myfile.asm -o myfile.o
:: Link using LD
ld myfile.o -Ttext 0x500 -s -o myfile.tmp
:: Use objdump to output as a flat binary
objcopy -O binary myfile.tmp myfile
但是生成的 myfile 看起来像垃圾:
00000000 66B8C105E8B8 mov eax,0xb8e805c1
00000006 0000 add [bx+si],al
我在上面尝试了一些变体,但没有一个能产生我所期望的结果,所以现在我很困惑:
- 谁能帮我理解这里发生了什么?
- 另外,我应该怎么做才能让我对生成的二进制文件中的地址解析到何处进行同样的控制?
【问题讨论】: