【问题标题】:What is "object" in "object file" and why is it called this way? [duplicate]“对象文件”中的“对象”是什么,为什么这样称呼它? [复制]
【发布时间】:2012-01-05 04:52:07
【问题描述】:

有人问我一个问题:“什么是‘目标文件’?”。

看了 Wiki,只知道里面包含objects

但是这些对象是什么?为什么有人这样称呼它们?

【问题讨论】:

  • 这当然是一个非常古老的术语,因为 Unix 编译器至少从 1970 年代初就已经产生了 .o 文件,而且它与 OO 编程没有任何关系。
  • "对象:特定动作或感觉指向的人或事物。"生成该文件是运行编译器的对象,他们必须为其命名,所以...

标签: c++ c compilation linker object-files


【解决方案1】:

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

与可执行文件的区别在于目标文件没有链接,因此还没有定义对函数、符号等的引用(它们的内存地址基本上是空白的)。

当你用 GCC 编译 C 文件时:

gcc -Wall -o test test.c

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

但是当你这样做时:

gcc -Wall -o test.o -c test.c

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

当您有一个包含许多 C 文件的项目(例如)时,您会将每个 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)

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

你问:为什么这样称呼。我真的无法回答。为什么“蓝色”被命名为“蓝色”? ; )

这只是从……好吧,几十年……

有关信息,GCC 内部文档仅将目标代码定义为:

作品的“源代码”是指对作品进行修改的首选形式。 “目标代码”是指任何非源代码形式的作品。

历史原因相当模糊......

我只是希望您现在更好地理解什么是目标文件。我认为这比知道为什么这样称呼它更重要,因为单词只是,嗯,单词……

【讨论】:

  • 您真的应该尝试回答“为什么这样称呼它”,以使您的整个帖子都出色:D。
【解决方案2】:

我认为这个名称与区分以下各项有关:

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

目标文件包含:

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

来源:here

【讨论】:

    【解决方案3】:

    目标文件是源(文本)文件的二进制表示。它是不同部分的集合,用于分隔数据类型:

    • 文本部分
    • 数据部分
    • 堆栈

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

    例如在 *nix 系统上:

    objdump -d a.out

    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:
    

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 你应该删除最后一个假设 - 其余的都是 100% 好的
      • @SethCarnegie:“但是那些物体是什么……?”反正我把最后一句话说清楚了。
      • 您知道,我不是反对者之一(我不会在不留下非问题评论的情况下反对)。 “它的”也让我感到困惑;我认为应该是“他们是”。
      • 但您忘记提及将它们与可执行文件区分开来的最重要的事情。
      • 每个可执行文件都是一个目标文件,但每个目标文件都不是一个可执行文件
      猜你喜欢
      • 2010-11-17
      • 2015-07-17
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 2012-09-04
      相关资源
      最近更新 更多