【C语言】源代码的编译过程

27 篇文章 17 订阅

一、引言

我们平常编写C语言程序都是使用集成开发环境(IDE),这样的IDE通常是将编译和链接过程合并成一步完成,称为构建(Build)。这样对开发者虽然比较友好,但同时由于集成开发环境运行时掩盖了程序运行机制与机理,导致基础开发者并不知道从C源代码到二进制可执行文件生成中间到底经历哪些过程呢?接下来就来探索一下其中各个过程具体做了哪些工作。


二、C源代码的编译过程
c程序的基本编译过程具体如下图1和图2所示:

图1 C程序编译过程
图2 C语言源代码编译流程图
  1. 预编译
    源代码.c文件和相关头文件被预编译器预编译成一个.i文件;
    对于C++程序而言,一般是.cpp文件和头文件,预编译成.ii文件

预处理相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同。

//gcc进行预编译: 
gcc -E hello.c -o hello.i

具体工作:

1.删除所有“#define”,并展开所有宏定义(进行文本替换)
2.处理“#include”预编译指令,递归展开被包含的文件并插入到该预编译指令位置
3.处理“#if”、“#ifdef”、“#elif”、“endif”等条件编译指令
4.删除所有的注释(“//”和“/* */”)
5.添加行号和文件名标识,以便编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号
6.保留所有的“#program”指令,因为编译器编译时需要使用它们

  • 编译
    将.i文件翻译成汇编代码.s文件(在windows中,通常使用.asm便是汇编文件)
//gcc进行编译:
 gcc -S hello.i -o hello.s
 //新版本的gcc把预编译和编译两个步骤合并成一个步骤,使用了一个叫cc1的程序。
// 使用的命令如下:
 gcc -S hello.c -o hello.s

具体工作:

1.词法分析
(对构成源程序的字符串从左到右进行扫描分析,根据语言的词法规则识别一个一个具有独立意义的单词,例如:保留字(begin、end、for、while等)、标识符、常数、运算符、界符等)
2.语法分析
(根据语言的语法规则,把单词符号串分解成各类语法单位,如短语、子句、句子、程序段等,并检查各种语法单位在语法结构上的正确性)
3.语义分析
(对每种语法单位进行静态语义(静态语义指程序在语义上要遵守的规则)审查,然后分析其含义,并用另一种语言形式来描述这种语义)
4.中间代码生成及优化
5.生成汇编代码文件(生成指令)

  • 汇编
    通过汇编器as将编译完的汇编代码文件翻译成机器指令,并生成可重定位目标程序的.o文件,该文件为二进制文件,字节编码是机器指令。
//gcc进行汇编: 
gcc -c hello.s -o hello.o
//也可以使用gcc命令从源代码文件开始,经过预编译、编译、汇编直接输出目标文件
gcc -c hello.c -o hello.o
  • 链接
    通过链接器将一个个目标文件(或许还会有库文件)链接在一起生成一个完整的可执行程序。
    具体工作:

1.合并段和符号表
2.符号解析
3.分配地址和空间
4.符号重定义

  • 执行
    具体工作:

1.创建虚拟内存空间和物理内存(创建PCB)
2.加载指令和数据
3.将入口地址写入下一条指令寄存器


三、编译程序、翻译程序、汇编程序、解释程序的辨析

  • 翻译程序
    将用汇编语言或高级语言编写的程序转换成等价的机器语言程序,执行这种转换功能的程序统称为翻译程序

  • 汇编程序
    源程序为汇编语言,目标程序为机器语言的翻译程序

  • 编译程序
    源程序为高级语言编写的程序,目标程序为汇编语言或机器语言的翻译程序

  • 解释程序
    接受某个语言的程序并立即运行这个源程序。它的工作模式是一个个的获取、分析并执行源程序语句,一旦第一个语句分析结束,源程序便开始运行并且产生结果,它特别适合程序员以交互方式工作的情况,即希望在获取下一个语句之前了解每个语句的执行结果,允许执行时修改程序。

编译方式和解释方式实现高级语言的编译的区别:
在解释方式下,并不生成目标代码程序,而是直接执行源程序本身

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值