C 语言中的目标文件是什么?

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

163448 次浏览

对象文件就是在编译一个(或多个)源文件时得到的。

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

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

对象文件是编译阶段的实际输出。它主要是机器代码,但有信息,让链接器看到什么符号,以及它需要的符号,以便工作。(作为参考,“符号”基本上是全局对象、函数等的名称。)

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

  1. 对象文件就是编译后的文件本身。两者之间没有区别。

  2. 可执行文件是通过链接 Object 文件形成的。

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

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

下面是用高级语言(如 C)编写的这个过程的一个典型的高级流程

经过预处理

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

经过编译器

- > 给出汇编代码

通过一个组装程序

以机器语言给出存储在 OBJECT 文件中的代码

通过连接器

- > 获取可执行文件。

这个流程可能有一些变化,例如大多数编译器可以直接生成机器语言代码,而不需要经过汇编程序。类似地,他们可以为您进行预处理。尽管如此,为了更好地理解,分解这些组成部分还是很不错的。

对象文件是依赖于函数、符号和文本来运行程序的代码。就像旧的电传机一样,需要用电传打字机向其他电传机发送信号。

同样,处理器需要二进制代码才能运行,目标文件就像二进制代码一样,但是没有链接。链接会创建额外的文件,这样用户就不必自己编译 C 语言了。用户可以直接打开 exe 文件一旦目标文件链接到一些编译器,如 c 语言,或 vb 等。

有三种目标文件。

可重定位的目标文件

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

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

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

共享目标文件

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

可执行对象文件

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

在多个 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)上提到的所有命令

实际上是 Collect2,它是 ld 的包装器。