【问题标题】:Writing / linking a flat binary using NASM + LD使用 NASM + LD 编写/链接平面二进制文件
【发布时间】:2011-08-24 04:38:55
【问题描述】:

我正在创建自己的“玩具”操作系统,并且已经到了尝试理解链接和可执行格式的地步——特别是我有一个平面文件二进制格式可执行文件,我正在将其加载到内存中地址0x500,然后直接调用。例如,考虑以下两条指令(我知道这是人为的,我只想在我的示例中同时包含 callmov

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

我在上面尝试了一些变体,但没有一个能产生我所期望的结果,所以现在我很困惑:

  • 谁能帮我理解这里发生了什么?
  • 另外,我应该怎么做才能让我对生成的二进制文件中的地址解析到何处进行同样的控制?

【问题讨论】:

    标签: assembly linker nasm ld


    【解决方案1】:

    所以我发现我做错了很多事情,其中​​最严重的是尝试使用 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 位。

    花费了大量的实验和阅读模糊的论坛链接,但结果我现在对整个事情有了更好的理解。

    【讨论】:

      猜你喜欢
      • 2010-09-24
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 2010-12-02
      • 2013-03-02
      相关资源
      最近更新 更多