我正在创建自己的“玩具”操作系统,现在我正在尝试理解链接和可执行文件格式 - 特别是我有一个扁平文件二进制格式的可执行文件,我正在将其加载到地址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上):
Google搜索导致我找到了这个邮件列表,看起来很有道理,因此我尝试了以下方法:ld:无法对非PE输出文件执行PE操作
:: 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
我尝试了以上几种变化,但没有一种能够产生我期望的结果,所以现在我感到相当困惑:
- 有人可以帮我理解这里正在发生什么吗?
- 还有我应该做些什么来获得对生成二进制文件中地址被解析到的控制权呢?