什么';C语言中的对象文件是什么?

什么';C语言中的对象文件是什么?,c,compilation,linker,object-files,C,Compilation,Linker,Object Files,我正在阅读C语言中的库,但还没有找到关于对象文件是什么的解释。任何其他编译文件与对象文件之间的真正区别是什么? 如果有人能用人类语言解释,我会很高兴。当你编译一个(或多个)源文件时,你就会得到一个对象文件 它可以是完全完成的可执行文件或库,也可以是中间文件 对象文件通常包含本机代码、链接器信息、调试符号等。对象文件是编译阶段的实际输出。它主要是机器代码,但有一些信息允许链接器查看其中的符号以及工作所需的符号。(作为参考,“符号”基本上是全局对象、函数等的名称) 链接器获取所有这些对象文件并将它们

我正在阅读C语言中的库,但还没有找到关于对象文件是什么的解释。任何其他编译文件与对象文件之间的真正区别是什么?

如果有人能用人类语言解释,我会很高兴。

当你编译一个(或多个)源文件时,你就会得到一个对象文件

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


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

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

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

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

  • 可执行文件是通过链接对象文件形成的

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

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

  • 这是一个典型的高级流程,用于高级语言(如C)中的代码

    -->通过预处理器

    -->要给出优化的代码,仍然使用C语言

    -->通过编译器

    -->给出汇编代码

    -->通过汇编程序

    -->用机器语言给出存储在目标文件中的代码

    -->通过链接器

    -->获取可执行文件


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

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


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

    有3种对象文件

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

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

    整个过程将是:预处理器(cpp)将在交流电上运行。其输出(仍然是源代码)将馈送到编译器(cc1)。其输出(汇编)将输入汇编程序(as),汇编程序将生成
    可重定位对象文件
    。该文件包含目标代码和链接(如果使用了
    -g
    ,则进行调试)元数据,不能直接执行

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

    可执行对象文件 包含可直接加载到内存(例如,由加载程序加载)并随后执行的机器代码

    在多个可重新定位的对象文件上运行链接器的结果是一个可执行的对象文件。链接器通过将所有相同类型的输入部分(例如,
    .data
    )合并到相同类型的输出部分,从左到右合并命令行中的所有输入对象文件。它使用
    符号分辨率
    重定位

    奖金如下: 当针对
    静态库进行链接时,输入对象中引用的函数将复制到最终可执行文件中。
    使用
    动态库
    将创建一个符号表,该表将启用与库函数/全局函数的动态链接。因此,结果是一个部分可执行的对象文件,因为它依赖于库。如果库不存在,文件将无法再执行)

    链接过程可按如下方式进行:
    ld a.o-o myexecutable

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


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

    实际上,对于大多数编译器,编译阶段的输出是汇编代码,然后编译器调用汇编程序将其转换为对象文件。@chrisdd:旧编译器通常是这样。现在,除非您要求编译器生成汇编代码,否则编译器不会生成汇编代码,而且通常不会在内部使用。但无论如何,汇编都是编译阶段的一个子阶段,因此所有这些都是没有意义的。单个目标文件可以执行吗?@Honey:通常不会。即使目标文件的格式是为执行而设计的(基本上从来都不是),关于“工作所需的符号”的部分基本上也会扼杀交易。即使是标准的“hello world”也需要