在Linux中使用gcc编译“hello.c”文件,只须使用最简单的指令,如下所示

$gcc hello.c -o hello

事实上,上述过程可以分解成四个部分:预处理(预编译)、编译、汇编、链接

一、预处理

首先是源代码文件“hello.c”和相关头文件,如stdio.h等被预编译器cpp预编译成一个“.i”文件。

第一步预编译过程相当于如下指令(-E表示只进行预编译)

$gcc -E hello.c -o hello.i

预编译过程主要处理源代码文件中的以“#”开头的预编译指令,如#include,#define等,主要处理过程如下

(1)将所有“#define”删除,并展开所有宏定义

(2)处理所有条件预编译指令,如“#if”,"#ifdef"

(3)删除所有注释

(4)添加行号和文件名标识

(5)保留所有#pragma编译器指令

二、编译

编译过程就是将预处理完的文件进行一系列,词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件。主要处理过程如下

$gcc -S hello.i -o hello.s

现在版本的GCC把预编译和编译两个步骤合成一个步骤,用一个程序来完成这个步骤,对于C语言程序,用ccl这个程序;C++用cclplus;Objective-C用cclobj等,所以gcc只是这些后台程序的包装,它会根据不同的参数要求去调用预编译编译程序cc1、汇编器as、链接器Id

编译过程一般分为六步:扫描、语法分析、语义分析、源代码优化,代码生成和目标代码优化

1.词法分析

首先源代码被输入到扫描器,进行词法分析,运用一种类似于有限状态机的算法可以将源代码的字符序列分割成一系列的记号,如:关键字、标识符、字面量(数字、字符串等)和特殊符号(加号、等号等)。

对于一些有预处理的语言,比如C语言,它的宏替换和文件包含等工作一般不归入编译器的范围,而是交给一个独立的预处理器。

2.语法分析

语法分析器 将对由扫描器产生的记号进行语法分析,从而产生语法树 (由语法分析器生成的语法树就是以表达式为节点的树)。

3.语义分析

语法分析仅仅完成了对表达式的语法层面的分析,而不能了解这个语句是否有意义,这就需要语义分析器来完成。

编译器所能分析的是静态语义,而运行期间能确定的语义为动态语义,语义分析就是完成声明和类型的匹配,类型的转换。

4.中间语言生成

由于需要进行源代码优化,而在语法树上直接优化比较困难,所以源代码优化器往往将整个语法树转化成中间代码,它是语法树的顺序表示,其实它已经非常接近目标代码了。但是它一股跟目标机器和运行时环境是无关的,比如它不包含数据的尺寸、变量地址和寄存器的名字等。中间代码有很多种类型,在不同的编译器中有着不同的形式,比较常见的有:三地址码 和 P ﹣代码。

中间代码使得编译器可以被分为前端和后端。编译器前端负责产生机器无关的中间代码,编译器后端将中间代码转换成目标机器代码。

5.目标代码生成与优化

源代码级优化器产生中间代码标志着下面的过程都属于编辑器后端。编译器后端主要包括代码生成器和目标代码优化器,代码生成器将中间代码转换成目标机器代码。

目标代码优化器对目标代码进行优化,比如选择合适的寻址方式、使用位移来代替乘法运算、删除多余的指令等。

三、汇编

汇编器是将汇编代码转化成机器可以执行的指令。主要处理过程如下:

$gcc -c hello.i -o hello.o

或者用汇编器as

$as hello.s -o hello.o

四、链接

链接的主要内容就是把各个模块之间相互引用的部分都处理好,使得各个模块之间可以正确的衔接

主要过程如下:

$gcc hello.o -o hello

注:参考文献《程序员的自我修养》

Linux GCC编译详细相关推荐

  1. linux内核编译最详细,Linux内核编译详细教程,linux内核编译

    Linux内核编译详细教程,linux内核编译 尝试编译下Linux-kernel 4.14.14,使用Ubuntu 16.04 64位 系统. kernel-4.14.14 内核文件约96MB,解压 ...

  2. Linux gcc编译c/c++基本过程

    Linux系统下开发c++程序,那么gcc编译器就是我们绕不过去的一道坎.gcc是GNU出品的一款可以在多种硬件平台上编译处可执行程序的超级编译器,其执行效率比普通的编译器要高出20%~30%左右,而 ...

  3. linux gcc编译C程序 分享

    一个c语言程序从源文件到生成可执行文件,编译器需要共经历4个步骤: 1) 预处理:把c文件中预处理命令扫描处理完毕,即对源代码文件中的文件包含(#include).预编译语句(如宏定义#define等 ...

  4. linux gcc编译undefined reference to `stricmp'问题

    最近gcc编译遇到这样的问题:undefined reference to `stricmp'. 查了下,stricmp是Windows特有函数. 解决方法: stricmp是Microsoft's ...

  5. Linux gcc编译过程及动态/静态库制作

    Linux库概念及如何制作静态库和动态库 1: gcc编译的过程 2: 分文件编程 3: 库(静态库和动态库) 3.1: 库的基本介绍 3.2: 静态和动态库的区别 3.3: 库的制作及使用 3.3. ...

  6. linux gcc编译常见问题,常见gcc编译警告整理以及解决方法 - 常见gcc编译警告整理以及解决方法...

    三.常见gcc编译警告整理以及解决方法 1.warning: no newline at end of file 在文件最后一行加上回车键 解释:在<Rationale for the C99 ...

  7. linux gcc 编译找不到头文件,找不到库

    找不到头文件 解决方式 (头文件均为编译时刻使用) 1.把头文件路径写成绝对路径,把路径写全,如 (相对路径也行) #include "/usr/include/stdio.h" ...

  8. linux gcc编译c文件头文件,使用GCC编译器编译C语言

    GCC编译C源代码有四个步骤:预处理-->编译-->汇编-->链接. 可以利用GCC的参数来控制执行的过程,这样就可以更深入的了解编译C程序的过程. 下面将通过对一个程序的编译来演示 ...

  9. linux gcc编译错误:statically linked applications requires at runtime the shared libraries

    statically linked applications requires at runtime the shared libraries from the glibc version used ...

  10. [转] Linux GCC 编译使用

    GCC使用 在使用GCC编译程序时,编译过程可以被细分为四个阶段: 预处理(Pre-Processing) 编译(Compiling)汇编(Assembling) 链接(Linking). 例如:  ...

最新文章

  1. 利用inotifywait监控主机文件和目录
  2. python编程基础知识体系_Python 编程核心知识体系-基础|数据类型|控制流(一)...
  3. Android开发 - 掌握ConstraintLayout(四)创建基本约束
  4. 网上选课系统的php代码,网上选课系统(论文+程序)
  5. Webpack不生成index.html
  6. php 正三角塔,PHP 环境塔建与数据类型转换
  7. Java笔记-模拟QQ三方登录(单点登录2.0)
  8. [误将两块磁盘挂载到根目录][解决办法]
  9. 个人博客网站建设_利用Github+Jeklly搭建个人博客网站
  10. 2021年互联网公司春招有何新变化?大厂要求是这样!
  11. Web服务器处理Servlet处理请求过程
  12. VC知识库大讲堂C++系列教程(目前最新)
  13. IIS中间件渗透总结
  14. 由中缀、后缀确定前缀表达式
  15. 支付宝首次揭秘红包技术
  16. 平面设计和3D美术设计哪个更好就业?次世代又是什么?
  17. audio驱动之简单介绍
  18. dva的用法_dva 的基本用法
  19. 《一往无前》10岁的小米,给世界讲了一个怎样的故事?
  20. hadoop性能优化(调优)

热门文章

  1. 搭建云上博客——阿里云实验室 学习笔记
  2. matlab求均值、方差
  3. 计算机应用基础好不好考,计算机应用基础好考么
  4. 汇编语言 XCHG指令
  5. 2018我读过的那些书
  6. H3CSE认证网络工程师视频课程-交换技术-宋文峰-专题视频课程
  7. 《麦肯锡方法》第13章 与客户合作-思维导图
  8. 【算法导论】有向图的可达矩阵
  9. 【华为云技术分享】从软件开发到 AI 领域工程师:模型训练篇
  10. CTex下载地址和方法