GCC编译器原理(二)------编译原理一:目标文件

发布时间:2024-08-22  

一、目标文件

在 UNIX® 和 Linux® 中,任何事物都是文件。UNIX 和 Linux 编程实际上是编写处理各种文件的代码。系统由许多类型的文件组成,但目标文件具有一种特殊的设计,提供了灵活和多样的用途。


目标文件是包含带有附加地址和值的助记符号的路线图。这些符号可以用来对各种代码段和数据段进行命名,包括经过初始化的和未初始化的。它们也可以用来定位嵌入的调试信息,就像语义 Web,非常适合由程序进行阅读。


编译器可以将我们在代码编辑器中创建的文本转换为目标文件。最初,目标文件被称为代码的中间表示形式,因为它用作连接编辑器(即连接器)的输入,而连接编辑器最终完成整个任务并生成可执行的程序作为输出。


从代码到可执行代码的转换过程经过了良好的定义并实现了自动化,而目标文件是这个链中有机的连接性环节。在这个转换过程中,目标文件作为连接编辑器所使用的映象,使得它们能够解析各种符号并将不同的代码和数据段连接在一起形成统一的整体。


1.1 目标文件的格式

计算机编程领域中存在许多著名的目标文件格式。DOS 系列包括 COM、OBJ 和 EXE 格式。UNIX 和 Linux 使用 a.out、COFF 和 ELF。Microsoft® Windows® 使用可移植的执行文件 (PE) 格式,而 Macintosh 使用 PEF、Mach-O 和其他文件格式。


最初,各种类型的计算机具有自己独特的目标文件格式,但随着 UNIX 和其他在不同硬件平台上提供可移植性的操作系统的出现,一些常用的文件格式上升为通用的标准。其中包括 a.out、COFF 和 ELF 格式。


要了解目标文件,需要一组可以读取目标文件中不同部分并以更易于读取的格式显示这些内容的工具。


1.2 UNIX 目标文件

写一个简单的程序:hello.c

C 编译器的正常输出是用于所指定的目标处理器的汇编代码。汇编代码是汇编器的输入,在缺省情况下,汇编器将生成所有目标文件的祖先,即 a.out 文件。这个名称本身表示汇编输出 (Assembler Output)。要创建 a.out 文件,可以在 shell 窗口中输入下面的命令:gcc hello.c


最新的 C 编译器将编译和汇编步骤组合成一个步骤。我们可以指定不同开关选项以查看 C 编译器的汇编输出。通过输入下面的命令,我们可以看到 C 编译器的汇编输出:gcc -S hello.c

在当前目录下会生成 hello.s 文件,即为汇编输入文本。


接下来研究目标文件,其中使用的有价值的工具有:

nm:列出目标文件中的符号。

objdump:显示目标文件中的详细信息。

readelf:显示关于 ELF 目标文件的信息。

1.2.1 nm:列出目标文件中的符号

执行命令:nm a.out

这些包含可执行代码的段称为正文段。同样地,数据段包含了不可执行的信息或数据。另一种类型的段,称为 BSS 段,它包含以符号数据开头的块。


对于 nm 命令列出的每个符号,它们的值使用十六进制来表示(缺省行为),并且在该符号前面加上了一个表示符号类型的编码字符。


常见的各种编码包括:

A 表示绝对 (absolute),这意味着不能将该值更改为其他的连接;

B 表示 BSS 段中的符号;

C 表示引用未初始化的数据的一般符号。

可以将目标文件中所包含的不同的部分划分为段。段可以包含可执行代码、符号名称、初始数据值和许多其他类型的数据。


1.2.2 objdump:显示目标文件中的详细信息

通过输入下面的命令,可以看到目标文件中包含可执行代码的每个段的汇编清单。


objdump -d a.out


命令生成的代码如下所示:


  1 a.out:     file format elf64-x86-64

  2 

  3 

  4 Disassembly of section .init:

  5 

  6 00000000004003c8 <_init>:

  7   4003c8:   48 83 ec 08             sub    $0x8,%rsp

  8   4003cc:   48 8b 05 25 0c 20 00    mov    0x200c25(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>

  9   4003d3:   48 85 c0                test   %rax,%rax

 10   4003d6:   74 05                   je     4003dd <_init+0x15>

 11   4003d8:   e8 43 00 00 00          callq  400420 <__libc_start_main@plt+0x10>

 12   4003dd:   48 83 c4 08             add    $0x8,%rsp

 13   4003e1:   c3                      retq   

 14 

 15 Disassembly of section .plt:

 16 

 17 00000000004003f0 :

 18   4003f0:   ff 35 12 0c 20 00       pushq  0x200c12(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>

 19   4003f6:   ff 25 14 0c 20 00       jmpq   *0x200c14(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>

 20   4003fc:   0f 1f 40 00             nopl   0x0(%rax)

 21 

 22 0000000000400400 :

 23   400400:   ff 25 12 0c 20 00       jmpq   *0x200c12(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>

 24   400406:   68 00 00 00 00          pushq  $0x0

 25   40040b:   e9 e0 ff ff ff          jmpq   4003f0 <_init+0x28>

 26 

 27 0000000000400410 <__libc_start_main@plt>:

 28   400410:   ff 25 0a 0c 20 00       jmpq   *0x200c0a(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>

 29   400416:   68 01 00 00 00          pushq  $0x1

 30   40041b:   e9 d0 ff ff ff          jmpq   4003f0 <_init+0x28>

 31 

 32 Disassembly of section .plt.got:

 33 

 34 0000000000400420 <.plt.got>:

 35   400420:   ff 25 d2 0b 20 00       jmpq   *0x200bd2(%rip)        # 600ff8 <_DYNAMIC+0x1d0>

 36   400426:   66 90                   xchg   %ax,%ax

 37 

 38 Disassembly of section .text:

 39 

 40 0000000000400430 <_start>:

 41   400430:   31 ed                   xor    %ebp,%ebp

 42   400432:   49 89 d1                mov    %rdx,%r9

 43   400435:   5e                      pop    %rsi

 44   400436:   48 89 e2                mov    %rsp,%rdx

 45   400439:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp

 46   40043d:   50                      push   %rax

 47   40043e:   54                      push   %rsp

 48   40043f:   49 c7 c0 c0 05 40 00    mov    $0x4005c0,%r8

 49   400446:   48 c7 c1 50 05 40 00    mov    $0x400550,%rcx

 50   40044d:   48 c7 c7 26 05 40 00    mov    $0x400526,%rdi

 51   400454:   e8 b7 ff ff ff          callq  400410 <__libc_start_main@plt>

 52   400459:   f4                      hlt    

 53   40045a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

 54 

 55 0000000000400460 :

 56   400460:   b8 3f 10 60 00          mov    $0x60103f,%eax

 57   400465:   55                      push   %rbp

 58   400466:   48 2d 38 10 60 00       sub    $0x601038,%rax

 59   40046c:   48 83 f8 0e             cmp    $0xe,%rax

 60   400470:   48 89 e5                mov    %rsp,%rbp

 61   400473:   76 1b                   jbe    400490

 62   400475:   b8 00 00 00 00          mov    $0x0,%eax

 63   40047a:   48 85 c0                test   %rax,%rax

 64   40047d:   74 11                   je     400490

 65   40047f:   5d                      pop    %rbp

 66   400480:   bf 38 10 60 00          mov    $0x601038,%edi

 67   400485:   ff e0                   jmpq   *%rax

 68   400487:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)

 69   40048e:   00 00 

 70   400490:   5d                      pop    %rbp

 71   400491:   c3                      retq   

 72   400492:   0f 1f 40 00             nopl   0x0(%rax)

 73   400496:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)

 74   40049d:   00 00 00 

 75 

 76 00000000004004a0 :

 77   4004a0:   be 38 10 60 00          mov    $0x601038,%esi

 78   4004a5:   55                      push   %rbp

 79   4004a6:   48 81 ee 38 10 60 00    sub    $0x601038,%rsi

 80   4004ad:   48 c1 fe 03             sar    $0x3,%rsi

 81   4004b1:   48 89 e5                mov    %rsp,%rbp

 82   4004b4:   48 89 f0                mov    %rsi,%rax

 83   4004b7:   48 c1 e8 3f             shr    $0x3f,%rax

 84   4004bb:   48 01 c6                add    %rax,%rsi

 85   4004be:   48 d1 fe                sar    %rsi

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    是大括号不对应?是不是分号写成了中文输入格式?是不是“|”写成了”||”. 这个是程序编程过程中最常用的方法。 处理方法2: 将编译的错误提示,点击右键复制,然后百度搜索相关信息。 这个......
    qwt移植到OK6410(2024-09-12)
    你就必须在Qt Creator中进行相关的设置,也就是添加一个工具链。 第四步:我们来进行编译,点击 Build ALL,编译的过程中会报错,是关于一些Designer的头文件找不到,因为qwt自定......
    x264编码的ARM移植;写一下最近移植x264的过程。 最新的版本(我最开始用的是20090715这个)已经有cross-compile的支持了,移植应该还是很顺利的。但是这个版本的win下编译......
    GCC编译器原理(三)------编译原理三:编译过程(3)---编译之汇编以及静态链接【1】;三、汇编 编译过程就是生成汇编代码的过程,在编译过程中,也会调用汇编器 as,将源......
        @ main函数返回,程序暂停 halt:     B   halt 为了方便对比,C程序与实验2的相同; 编译的makefile和之前的也相同; 3.4.实验结果 程序编译下载后,可以......
    嵌入式软件开发常用的套路与技巧;01. 调试相关的宏 在Linux使用gcc编译程序的时候,对于调试的语句还具有一些特殊的语法。本文引用地址:gcc编译的过程中,会生成一些宏,可以......
    Linux移植之auto.conf、autoconf.h、Mach-types.h的生成过程简析;在Linux移植之make uImage编译过程分析中分析了uImage文件产生的过程,在......
    STM32单片机程序编译及下载配置;前言 当拿到STM32单片机开发板的时候,程序的编译和下载将是我们踏入STM32单片机开发的第一步。本章详细介绍程序的编译和下载。包括:Keil5工程编译......
    务级切换,OSIntCtxSw是中断级切换,是从中断退出时切换到一个任务中,从中断切换到任务的过程中,CPU的寄存器入栈工作已经完成。 OSCtxSw   PUSH    {R4, R5}   LDR     R4......
    口中断 0023H 定时器2 溢出 002BH interrupt 和 using 都是 C51 的关键字。C51 中断过程通过使用 interrupt 关键字和中断号(0 到 31)来实现。中断号指明编译器中断程序......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>