【问题标题】:Is it possible to produce working binary without linker?是否可以在没有链接器的情况下生成工作二进制文件?
【发布时间】:2018-02-22 09:28:14
【问题描述】:

据我所知,编译器会将源代码转换为机器代码。但是这段代码没有任何与操作系统相关的部分,链接器将它们添加到文件中。

但是是否有可能在没有链接器的情况下制作一些可执行文件?

【问题讨论】:

    标签: linker d


    【解决方案1】:

    从字面上回答您的问题 - 是的,可以在没有链接器的情况下制作执行文件:您不需要编译器或链接器来生成机器代码。二进制文件是一系列操作码和相关信息(偏移量、地址等)。如果你打开一个二进制编辑器,然后输入一些操作码并制作一个程序。保存并运行它。

    当然,二进制文件将是特定于处理器的,就像您编译了一个二进制(本机)执行程序一样。这是对 Intel x86 操作码的参考。 http://ref.x86asm.net/coder32.html.

    但是,如果您问“我可以在没有链接器的情况下将源文件直接编译成执行文件吗?”然后纯粹地说:不 - 除非编译器具有集成在其中的链接器的各个方面。编译器生成中间对象,这些对象传递给链接器以将它们“链接”到二进制文件中,例如库或执行程序。没有链接步骤,管道是不完整的。

    【讨论】:

    • 好吧,你在 16 位 DOS 上不用链接器! .com 文件只是一些具有固定偏移量的可执行代码。 :)
    【解决方案2】:

    让我们首先做一个被认为是真实的声明,编译器不会生成可以立即执行的机器代码(JIT 可以,但我们忽略它)。

    相反,它们生成文件(对象、静态、动态、可执行文件)来描述它们包含的内容以及符号组。符号可以是全局变量或函数。

    但是符号就像文件本身一样包含元数据。这个元数据非常重要。看到存储在符号中的机器代码是目标架构的原始指令,但它不知道内存存储在哪里。

    虽然现代 CPU 为每个进程提供了自己的地址空间,但一个符号可能不会出现,也可能不会两次出现在同一个地址中。在最近,这是一种安全措施,但在过去,动态链接可以正常工作。

    因此,当操作系统加载可执行文件或共享库时,它可以将其放置在任何它想要的位置,并通过这样做使其不可重复。否则我们都必须开始关心并说“这个文件包含我打算执行的 100% 的代码”。通常在加载符号表中的原始二进制文件时,通过使用 RAM 中的符号位置对其进行修补来进行转换。让一切正常工作。

    总而言之,编译器会发出允许动态修补程序集的文件 在执行之前。如果不是这样,我们将生活在一个非常限制和有问题的世界中。

    链接器甚至有脚本来改变它们的操作方式。它们是使我们的程序正常运行所需的非常复杂和精致的软件。

    如果您想了解这些格式的真正复杂程度,请阅读 PE-COFF 和 ELF 标准。

    【讨论】:

      猜你喜欢
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-17
      • 2018-11-15
      • 2021-10-11
      • 2012-09-07
      • 2012-10-25
      相关资源
      最近更新 更多