什么是"对象文件"中的"对象",为什么这样称呼?

sth*_*m58 18 c c++ linker compilation object-files

我被问到一个问题:"什么是'目标文件'?".

看完Wiki后,我只知道它包含了对象.

但那些对象是什么以及为什么有人这样称呼他们呢?

Mac*_*ade 21

目标文件(或目标代码)是编译器从源代码生成的机器代码文件.

与可执行文件的不同之处在于目标文件没有链接,因此尚未定义对函数,符号等的引用(它们的内存地址基本上是空白的).

使用GCC编译C文件时:

gcc -Wall -o test test.c
Run Code Online (Sandbox Code Playgroud)

在这里,您正在编译AND链接.因此,您将获得一个可执行文件,其中包含其包含的符号(库,标头等)的所有内存地址引用.

但是当你这样做时:

gcc -Wall -o test.o -c test.c
Run Code Online (Sandbox Code Playgroud)

你将生成和对象文件.它也是机器代码,但它需要链接才能生成可执行文件或库.

如果您的项目包含许多C文件(例如),您将每个文件编译成目标代码,然后将所有目标文件链接在一起以生成最终产品.

例如:

gcc -Wall -o foo.o -c foo.c              // Object file for foo.c
gcc -Wall -o bar.o -c bar.c              // Object file for bar.c
gcc -Wall -o main.o -c main.c            // Object file for main.c
gcc -Wall -o software foo.o bar.o main.o // Executable (foo + bar + main)
Run Code Online (Sandbox Code Playgroud)

术语对象在这里代表未链接机器代码的序列(基本上).目标文件包含对象.

你问:为什么这样打电话.我无法回答.为什么"蓝色"被命名为"蓝色"?; )

这只是自......以来使用的术语......好吧,几十年......

有关信息,GCC Internals文档仅将对象代码定义为:

作品的"源代码"是指对其进行修改的首选作品形式."对象代码"是指作品的任何非源形式.

对历史原因很模糊......

我希望你现在能更好地理解什么是目标文件.我认为这比知道为什么它被称为更重要,因为单词只是,好吧,单词......

  • 你应该真的尝试回答"为什么这就是这种方式"让你整个帖子都很出色:D. (2认同)

Mat*_*ick 7

我相信这个名字与区分:

  • 人类代码 - 源代码
  • 机器代码 - 目标代码

对象文件包含:

  • 标题信息:有关文件的总体信息,例如代码的大小,从中翻译的源文件的名称以及创建日期.
  • 目标代码:由编译器或汇编器生成的二进制指令和数据.
  • 重定位:目标代码中的位置列表,当链接器更改目标代码的地址时,必须修复这些位置.
  • 符号:此模块中定义的全局符号,要从其他模块导入或由链接器定义的符号.
  • 调试信息:有关链接但不需要用于调试器的目标代码的其他信息.这包括源文件和行号信息,本地符号,目标代码使用的数据结构的描述,例如C结构定义.

来源:这里


Fai*_*Dev 7

目标文件是源(文本)文件的二进制表示。它是分隔数据类型的各个部分的集合:

  • 文本部分
  • 数据部分

根据您的编译器/环境,这些可能会有所不同。

例如在 *nix 系统上:

objdump -d a.out <--- 提供我们编译的a.cpp

disassembly of section .init:

08048278 <_init>:
 8048278:       55                      push   %ebp
 8048279:       89 e5                   mov    %esp,%ebp
 804827b:       83 ec 08                sub    $0x8,%esp
 804827e:       e8 61 00 00 00          call   80482e4 <call_gmon_start>
 8048283:       e8 b3 00 00 00          call   804833b <frame_dummy>
 8048288:       e8 9f 01 00 00          call   804842c <__do_global_ctors_aux>
 804828d:       c9                      leave
 804828e:       c3                      ret
Disassembly of section .plt:

08048290 <puts@plt-0x10>:
 8048290:       ff 35 78 95 04 08       pushl  0x8049578
 8048296:       ff 25 7c 95 04 08       jmp    *0x804957c
 804829c:       00 00                   add    %al,(%eax)
        ...

080482a0 <puts@plt>:
 80482a0:       ff 25 80 95 04 08       jmp    *0x8049580
 80482a6:       68 00 00 00 00          push   $0x0
 80482ab:       e9 e0 ff ff ff          jmp    8048290 <_init+0x18>

080482b0 <__libc_start_main@plt>:
 80482b0:       ff 25 84 95 04 08       jmp    *0x8049584
 80482b6:       68 08 00 00 00          push   $0x8
 80482bb:       e9 d0 ff ff ff          jmp    8048290 <_init+0x18>
Disassembly of section .text:
Run Code Online (Sandbox Code Playgroud)

然后,这里的各种调用命令将被各种库调用以调用实际的函数。


Moo*_*uck -4

根据您链接的页面,每个序列或对象通常包含主机完成某些任务的指令,可能还伴有相关数据和元数据(例如重定位信息、堆栈展开信息、注释、程序符号、调试或分析信息) )。

基本上,目标文件中的每个对象都是一个函数,以及链接器将其包含到完整程序中的相关信息。