gcc编译过程

gcc编译过程

文章目录

    • gcc编译过程
    • 1-预处理(Preproceessing)
    • 2-编译(Compilation)
    • 3-汇编(Assembly)
    • 4-链接(Linking)

一般在windows下编译代码的时候是直接生成了可执行文件,但是在linux下可以分布进行步步查看到,现在就来讲讲每个过程。

gcc编译四个步骤:
预处理器在预处理阶段将源代码(.c)转化为预处理文件(.i)
编译器在编译阶段将预处理文件(.i)转化为汇编文件(.s)
汇编器在汇编阶段将汇编文件(.s)转化为目标文件(.o)
链接器在链接阶段将目标文件(.o)转化为可执行程序(.out)gcc编译过程_第1张图片
以输出十次Hello World为例介绍,全文是在linux下ubuntu系统下进行的
gcc编译过程_第2张图片

1-预处理(Preproceessing)

预处理是读取c源程序,对其中的伪指令(以#开头的指令,也就是宏)和特殊符号进行“替代”处理;经过此处理,生成一个 没有宏定义、没有条件编译指令、没有特殊符号的输出文件。

预处理的过程主要处理包括以下过程:
将所有的#define删除,并且展开所有的宏定义处理所有的条件预编译指令,比如#if #ifdef #elif #else #endif等
处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。
删除所有注释 “//”和”/* */”. 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
保留所有的#pragma编译器指令,因为编译器需要使用它们。

gcc -E hello.c -o hello.i 或者 cpp hello.c -o hello.i
头文件已经被删除了(包含#的部分)
在这里插入图片描述
gcc编译过程_第3张图片

2-编译(Compilation)

编译原理大二的时候会修的,上课比较无聊,现在已经差不多都还给老师了
编译完成之后生成的是相应的汇编源文件,这里注意,不同的编译器生成的汇编源文件是不能共用的,这也是为什么c语言具有可移植性的原因
编译程序所要作得工作就是通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。 优化处理是编译系统中一项比较艰深的技术。它涉及到的问题不仅同编译技术本身有关,而且同机器的硬件环境也有很大的关系。优化一部分是对中间代码的优化,这种优化不依赖于具体的计算机。另一种优化则主要针对目标代码的生成而进行的。对于前一种优化,主要的工作是删除公共表达式、循环优化(代码外提、强度削弱、变换循环控制条件、已知量的合并 等)、复写传播,以及无用赋值的删除,等等。后一种类型的优化同机器的硬件结构密切相关,最主要的是考虑是如何充分利用机器的各个硬件寄存器存放的有关变量的值,以减少对于内存的访问次数。

gcc -S hello.i -o hello.s
我们使用的是gcc编译器生成的是X86的汇编代码,大二计算机科学与技术必修课《汇编语言》刚好可以用到,只是当时自己还不知道。
gcc编译过程_第4张图片

3-汇编(Assembly)

汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。 目标文件由段组成。
通常一 个目标文件中至少有两个段:
代码段(文本段):该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写;
数据段:主要存放程序中要用到的各种常量、全局变量、静态的数据。一般数据段都是可读,可写,可执行的;

4-链接(Linking)

每一个源文件(就是.c文件,上图中的程序1)都有对应的零碎文件(就是.h文件),通过预编译(通过#include实现)把.c和.h文件整合成一个组合C文件,这个组合C文件的扩展名为.i。把组合C文件编译成汇编文件.s,目标文件为机器指令(放在一个.o文件当中),单个目标文件是不能工作的,因为各个目标文件是相互支撑工作的。
把各个目标文件整合的过程就叫链接过程。整合后的文件就叫可执行程序,windows后缀为.exe,Linux后缀为.out
想了解具体可以参照这篇文章 https://blog.csdn.net/taotongning/article/details/106382171gcc编译过程_第5张图片
同时链接也分为两种:
动态链接
动态链接的优点:
(1)可执行文件很小;
(2)适合大规模软件开发,开发过程耦合度小、独立,便于不同开发人员和开发组织开发;
(3)不同编程语言按照约定可以使用同一套.dll库;

动态链接的缺点:
(1)速度没有静态链接快;
(2)不具有自完备,如果用户机器中没有.dll文件,程序将无法运行并且报错
在这里插入图片描述

静态链接
静态链接的优点:
(1)装载速度很快,运行速度比动态链接快;
(2)只需要开发人员在开发机上有完整的.lib文件,不需要在用户机器上有完整的.lib文件,自完备
静态链接的缺点:
(1)可执行文件很大,并且相同代码很多,资源浪费
在这里插入图片描述

你可能感兴趣的:(C语言,linux,ubuntu,c语言)