gpt4 book ai didi

assembly - 使用 NASM + LD 编写/链接平面二进制文件

转载 作者:行者123 更新时间:2023-12-04 01:29:43 29 4
gpt4 key购买 nike

我正在创建自己的“玩具”操作系统,并且已经到了尝试理解链接和可执行格式的地步 - 特别是我有一个平面文件二进制格式的可执行文件,我正在将其加载到地址 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: cannot perform PE operations on non PE output file



    谷歌搜索导致我找到 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

    我已经尝试了上面的一些变体,但它们都没有产生我所期望的,所以现在我很困惑:
  • 谁能帮我理解这里发生了什么?
  • 另外,我应该怎么做才能让我对结果二进制文件中的地址解析位置进行同样的控制?
  • 最佳答案

    所以我发现我做了很多错误的事情,其中​​最严重的是尝试使用 LD(不支持 16 位代码)编译和链接 16 位代码,并且没有使用 BITS 16 明确指定代码是 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 位。

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

    关于assembly - 使用 NASM + LD 编写/链接平面二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5979672/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com