Gcc编译器背后的故事

Gcc编译器背后的故事

引言:每个成功的软件程序背后都有一个强大的工具,它将代码变为现实——GCC编译器。从它的起初谦逊到如今成为全球使用最广泛和具有影响力的编译器之一,GCC编译器的故事充满了创新、合作和对卓越的不懈追求。让我们一起深入探索这个令人着迷的旅程,了解这个非凡软件是如何诞生的,以及那些塑造了我们今天构建和运行程序方式的未被讲述的故事。

一、GCC 简介

GCC(GNU C Compiler)原名GNU C语言编译器,是由GNU开发的编程语言译器,只能处理C语言。但其很快扩展,变得可处理C++,后来又扩展为能够支持更多编程语言,如Fortran、Pascal、Objective -C、Java、Ada、Go以及各类处理器架构上的汇编语言等,所以改名GNU编译器套件(GNU Compiler Collection)。GCC 编译器是 Linux 系统下最常用的 C/C++ 编译器,大部分 Linux 发行版中都会默认安装。GCC 编译器通常以gcc命令的形式在终端(Shell)中使用.对于要学习Linux的朋友来说,可以在Windows上做一个过渡。

二、Binutils大家族

GNU Binutils是一系列二进制工具的集合。主要包括:

  • ld —— GNU链接器
  • as—— GNU汇编器

但也包括以下二进制工具:

  • addr2line:从目标文件的虚拟地址获取文件的行号或符号。
  • ar:可以对静态库做创建、修改和提取的操作。
  • c++filt:反编译(反混淆,demangle)C++符号的工具。
  • dlltool:创建创建Windows动态库。
  • gold:另一种新的、更快的仅支持ELF的链接器。
  • gprof:性能分析(profiling)工具程序。
  • nlmconv:可以转换成NetWare Loadable Module(NLM)目标文件格式。
  • nm:显示目标文件内的符号信息。
  • objcopy:复制和转译目标文件。
  • objdump:显示目标文件的相关信息,亦可反汇编。
  • ranlib:产生静态库的索引。(和nm -s功能类似)
  • readelf: 显示ELF文件的内容。
  • size:列出目标文件或库文件的section大小。
  • strings:列出文件中可打印的字符串信息。
  • strip:从目标文件中移除符号信息。
  • windmc:Windows消息资源编译器。
  • windres:Windows资源文件编译器。

三、编译实例

main.c文件的编译运行过程

// main.c 代码
#include <stdio.h>
int main()
{
	printf("%s","Hello GCC!!!")	
}

1 . 预处理(Pre-Processing)

这个阶段主要处理源文件中的#indef、#include和#define预处理命令;
这里主要是把一些include的头文件和一些宏定义,放到源文件中。

  • 输入的是C语言的源文件

  • 输出 :生成一个中间/预加载文件 *.i(以 .i 结尾的文件)

  • 这个阶段对应的gcc命令如下:

    #gcc test.c(源文件) -o test.i(将结果生成的文件)

  • 说明:它通过对源文件test.c使用E选项来生成中间文件test.i

  • 实验代码:gcc -E main.c -o main.i

  • 效果图:在这里插入图片描述

2 . 汇编(Assembling)

  • 输入:中间文件*.i

  • 输出:编译后生成汇编编语言文件*.s

  • 这个阶段对应的gcc命令如下:
    #gcc -S(汇编) test.i -o test.s(汇编编语言文件)

  • 说明:它通过对源文件test.c使用S选项来生成汇编文件test.s

  • 实验代码:gcc -S main.i -o main.s

  • 效果图:在这里插入图片描述

3 . 编译(Compiling)

  • 输入文件:汇编文件*.s

  • 输出文件:二进制机器代码*.o

  • 这个阶段对应的gcc命令如下:

    #gcc -c(编译) test.s -o test.o

  • 实验代码:gcc -c main.s -o main.o

  • 效果图:在这里插入图片描述

在功能上,预处理、编译、汇编是3个不同的阶段
但gcc在实际操作时可以把这3个步骤合并为一个步骤来执行,即使用 -c选项:

  • 输入文件:源码*.c文件
  • 输出文件:二进制机器代码*.o
  • 这个阶段对应的gcc命令如下:

#gcc –c test.c -o test.o

// -o指定了output_filename
或 :
#gcc -c test.c
//省略-o output_filename
//默认输出为test.o
//与源文件同名,后缀为.o

4 . 链接(Linking)

  • 输入文件:二进制机器码*.o文件
  • 输出文件:与其它的机器代码和库文件汇集成一个可执行的二进制代码文件(无后缀)
  • 这个阶段对应的gcc命令如下:

​ #gcc (没有选项符号) test.o example.o -o test

  • 实验代码:gcc main.o -o main
  • 效果图:在这里插入图片描述

大佬友情链接

  • https://blog.csdn.net/weixin_47826078/article/details/120474122

  • https://zhuanlan.zhihu.com/p/561605849

  • https://www.cnblogs.com/tocy/p/gnu-binutils-simple-usage.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LX很爱吃葱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值