【问题标题】:What's an object file in C?什么是 C 中的目标文件?
【发布时间】:2011-12-04 19:42:13
【问题描述】:

我正在阅读 C 中的库,但我还没有找到关于什么是目标文件的解释。任何其他编译文件和目标文件之间的真正区别是什么?
如果有人能用人类语言解释,我会很高兴。

【问题讨论】:

标签: c compilation linker object-files


【解决方案1】:

目标文件是编译阶段的真正输出。它主要是机器代码,但具有允许链接器查看其中的符号以及工作所需的符号的信息。 (作为参考,“符号”基本上是全局对象、函数等的名称)

链接器获取所有这些目标文件并将它们组合成一个可执行文件(假设它可以,即:没有任何重复或未定义的符号)。如果您不告诉他们使用命令行选项“仅编译”,许多编译器将为您执行此操作(阅读:他们自己运行链接器)。 (-c 是一个常见的“只编译;不链接”选项。)

【讨论】:

  • 实际上,对于大多数编译器,编译阶段的输出是汇编代码,然后编译器调用汇编器将其转换为目标文件。
  • @ChrisDodd:老编译器经常出现这种情况。如今,除非您要求,否则编译器不会生成汇编代码,并且通常不会在内部使用它。但无论哪种方式,汇编都是编译阶段的一个子阶段,所以这一切都没有实际意义。
  • 单个对象文件可以执行吗?
  • @Honey:一般来说,不会。即使目标文件是为执行而设计的格式(它基本上从来不是),关于“它需要的符号才能工作”的那部分基本上会扼杀交易。甚至您的标准“hello world”也需要链接到 C 运行时库。
【解决方案2】:
  1. Object 文件是编译后的文件本身。两者没有区别。

  2. 通过链接Object文件形成一个可执行文件。

  3. 目标文件包含 CPU 可以理解的低级指令。这就是为什么它也被称为机器码。

  4. 此低级机器代码是指令的二进制表示,您也可以直接使用汇编语言编写它,然后使用汇编程序将汇编语言代码(以英语表示)处理成机器语言(以十六进制表示) .

这是此过程的典型高级流程,用于高级语言(例如 C)中的代码

-->经过预处理器

--> 给出优化的代码,仍然在 C 中

-->通过编译器

--> 给出汇编代码

--> 通过汇编程序

--> 以机器语言给出存储在对象文件中的代码

--> 通过链接器

--> 获取可执行文件。

此流程可以有一些变化,例如大多数编译器可以直接生成机器语言代码,而无需通过汇编程序。同样,他们可以为您进行预处理。不过,为了更好地理解,最好分解成分。

【讨论】:

  • 优化的代码不是在预处理阶段生成的,也不是在它之后立即生成的。预处理器只处理它自己的语言,仅此而已。优化发生在编译和组装阶段。
  • 是我们编译后得到的目标文件和机器语言的可执行文件一样。我很困惑,因为您说目标文件是在最后一步的第二步创建的,最后一步是可执行文件。那么,我们编译后得到的.0文件,就是可执行文件吗?
  • 不能单个目标文件也可以执行吗?
【解决方案3】:

有 3 种目标文件。

可重定位目标文件

以可以在链接时与其他可重定位目标文件组合的形式包含机器代码,以形成可执行目标文件。

如果你有一个a.c 源文件,要使用 GCC 创建它的目标文件,你应该运行: gcc a.c -c

整个过程是:预处理器 (cpp) 将在 a.c 上运行。它的输出(仍然是源代码)将输入编译器(cc1)。它的输出(汇编)将输入汇编器(as),汇编器将产生relocatable object file。该文件包含目标代码和链接(如果使用了-g,则进行调试)元数据,并且不能直接执行。

共享对象文件

可以在加载时或运行时动态加载的特殊类型的可重定位目标文件。共享库就是这类对象的一个​​例子。

可执行目标文件

包含可以直接加载到内存中的机器代码(由加载器,例如execve)并随后执行。

在多个relocatable object files 上运行链接器的结果是executable object file。链接器通过将所有相同类型的输入段(例如.data)合并到相同类型的输出段,从命令行从左到右合并所有输入目标文件。它使用symbol resolutionrelocation

奖励阅读:

当链接到static library 时,输入对象中引用的函数将被复制到最终的可执行文件中。 使用dynamic libraries 创建一个符号表,它将启用与库的函数/全局变量的动态链接。因此,结果是一个部分可执行的目标文件,因为它取决于库。如果该库不存在,则该文件将无法再执行)。

链接过程可以如下完成: ld a.o -o myexecutable

命令:gcc a.c -o myexecutable 将调用点 1 和点 3 中提到的所有命令 (cpp -> cc1 -> as -> ld1)

1:实际上是collect2,它是ld的包装器。

【讨论】:

    【解决方案4】:

    目标文件就是编译一个(或多个)源文件时得到的。

    它可以是完全完成的可执行文件或库,也可以是中间文件。

    目标文件通常包含本机代码、链接器信息、调试符号等。

    【讨论】:

      【解决方案5】:

      目标文件是依赖于函数、符号和文本来运行程序的代码。就像旧的电传机一样,需要电传才能将信号发送到其他电传机。

      与处理器需要二进制代码才能运行一样,目标文件就像二进制代码但没有链接。链接会创建附加文件,因此用户不必自己编译 C 语言。目标文件与c语言或vb等编译器链接后,用户可以直接打开exe文件。

      【讨论】:

        猜你喜欢
        • 2016-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多