在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. 一个实用技巧,告别手动画图,自动生成数据库 ER 图|原创
  2. java 项目使用 ajaxfileupload
  3. mysql报错:Column 'id' in field list is ambiguous,以及tp的三表联合查询语句,打印sql等
  4. 每个用户做独立的线程同步
  5. 操作系统中的死锁_操作系统中的死锁介绍
  6. 热门wordpress主题Essentials汉化绿色版[更至v2.0.0]
  7. java静态变量重复new_Java非静态成员变量之死循环(详解)
  8. 约瑟夫环非递归算法分析
  9. 史上首个人脸识别禁令出台,警察用来抓罪犯也不行!旧金山可真行
  10. tidb 架构 ~Tidb学习系列(5)
  11. 服务器 python cant open file_QQ炫舞转服系统-QQ炫舞官方网站-腾讯游戏
  12. Java机器学习库(Java ML)(一、分类)
  13. 【FTP工具】8UFTP工具是我自己比较经常用的,推荐。
  14. 天翼1号2021修改IMEI教程
  15. 蓝牙音响加拿大IC认证知多少
  16. Hyper-v集群高可用性配置
  17. Clickhouse 时间日期函数
  18. 安卓Apk安装出错:更新包与已安装应用的签名不一致,但在应用管理中却找不到这个已经卸载的应用
  19. swagger-ui导出word接口文档
  20. Android_adb shell dumpsys介绍

热门文章

  1. javaScript编码爱心表白
  2. 微加速度计的原理与应用
  3. css通过行内样式绑定背景图片
  4. 回顾2020年(1)
  5. CheckMarx源代码安全测试工具
  6. 伺服驱动器的接线与基本控制
  7. 云时代操作系统路在何方?麒麟信安的踏雪寻梅之道
  8. eclipse使用教程超详细讲解
  9. 动态规划—代码查重实验
  10. 计算机职业素养论文1500字,提升道德素养论文_职业素养论文2000字_工程师职业素养结课论文1500字...