我正在创建自己的“玩具”操作系统,我已经到了我试图理解链接和可执行格式的地步 - 特别是我有一个平面文件二进制格式可执行文件,我将其加载到内存中地址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,以便我可以链接其他对象,但经过大量的实验和阅读后,我仍然不明白为什么能够获得可靠的结果。
我收集的比为了产生类似的输出我需要:
.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
我已经尝试了上面的一些变化,但是它们都没有产生我期待的东西,所以现在我很困惑:
答案 0 :(得分:3)
所以我发现我做了多个错误的事情,其中最严重的是尝试使用LD编译和链接16位代码(不支持16位代码)并且没有明确指定代码是16位使用BITS 16
(这意味着NASM发出32位内存地址)。
这总体上解释了LD在上述情况的某些变化中给出的一些奇怪的错误消息,以及为什么链接二进制文件的拆卸是垃圾 - 我试图将32位代码反编译为16比特码,反之亦然。
理想情况下,我希望能够链接16位代码,但发现我不能用LD做这个(并且很少有可以这样做的替代方案)我决定当我用32位代码重复相同的事情时,理解最新情况。我的输入文件:
; Address locations are now 32 bits so I must use `eax` instead of `ax`
mov eax, some_label
call some_label
; some_label is at a different address into the resulting binary (because
; pointers are wider the resulting machine code is larger)
然后我使用以下内容链接:
:: Output as win32 object files - makes it possible to use -r with LD.
nasm -f win myfile.asm -o myfile.o
:: Link using LD - the -r flag prevents extra un-used code (e.g. __CTOR_LIST__) being generated - see the link in my original question text
ld myfile.o -Ttext 0x500 -s -r -o myfile.tmp
:: Use objdump to output as a flat binary - -j .text ensures that just the .text section is included which keeps the output file size down
objcopy -O binary -j .text myfile.tmp myfile
使用ndisasm
进行反汇编时,我需要指定-b 32
,以便将代码正确解释为32位。
需要进行大量的实验并阅读不起眼的论坛链接,但我现在理解整个事情要好得多。