程序详细编译过程【预处理、编译、汇编、链接】

本文详细介绍了C语言程序编译的四个主要步骤:预处理、编译、汇编和链接,包括预处理器处理宏、编译器进行词法分析和优化,汇编器将汇编代码转为目标文件,以及链接器合并依赖文件生成可执行程序。
摘要由CSDN通过智能技术生成

程序编译的整体流程 

#include<stdio.h>
int main()
{
    printf("hello, world\n");
    return 0;
}

        我们的代码会经过这4个环节,从而形成最终文件,c语言作为编译语言,用来向计算机发出指令。让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动。

预处理:展开头文件/宏替换/去掉注释/条件编译                      (  test.i  main .i  )
编译:检查语法,生成汇编                                                      (  test.s  main.s )
汇编:汇编代码转换机器码                                                        (  test.o main.o  )
链接:链接到一起生成可执行程序                                                      a.out
 

        hello程序的生命周期是从一个源程序(或者说源文件)开始的,即程序员通过编辑器创建并保存的文本文件。源程序实际上就是一个由0和1组成的(又称比)序列,8个位被组织成一组,称为字节。每个字节表示程序中的某些文本字符。像 hello.c这样只由ASCII字符构成的文本称为文本文件,其他所有的文件都称为二进制文件。

        为了在系统上运行这个程序,每条C语句都必须被其他程序转化为一系列的低级机器语言指令,然后这些指令按照一种为可执行目标程序的格式打好包,并以二进制磁盘文件的形式存放起来。目标程序也称为可执行目标文件

        在Unix系统上,从源文件到目标文件的转化是由编译器驱动程序完成的。

 

一.预处理阶段

  1. 预处理器(cpp)将所有的#define删除,并且展开所有的宏定义。
  2. 处理所有的条件预编译指令,比如#if、#ifdef、#elif、#else、#endif等。
  3. 处理#include预编译指令,将被包含的文件直接插入到预编译指令的位置。
  4. 删除所有的注释。
  5. 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
  6. 保留所有的#pragma编译器指令,因为编译器需要使用它们。
  7. gcc -E hello.c -o hello.i
    使用以上命令来进行预处理, 预处理得到的另一个程序通常是以.i作为文件扩展名。

 

二.编译阶段

编译器(ccl)将预处理完的文本文件hello.i进行一系列的词法分析、语法分析、语义分析和优化,翻译成文本文件hello.s,它包含一个汇编语言程序。

编译过程可分为6步:扫描(词法分析)、语法分析、语义分析、源代码优化、代码生成、目标代码优化

  1. 词法分析:扫描器(Scanner)将源代的字符序列分割成一系列的记号(Token)。lex工具可实现词法扫描。
  2. 语法分析:语法分析器将记号(Token)产生语法树(Syntax Tree)。yacc工具可实现语法分析(yacc: Yet Another Compiler Compiler)。
  3. 语义分析:静态语义(在编译器可以确定的语义)、动态语义(只能在运行期才能确定的语义)。
  4. 源代码优化:源代码优化器(Source Code Optimizer),将整个语法书转化为中间代码(Intermediate Code)(中间代码是与目标机器和运行环境无关的)。中间代码使得编译器被分为前端和后端。编译器前端负责产生机器无关的中间代码;编译器后端将中间代码转化为目标机器代码。
  5. 目标代码生成:代码生成器(Code Generator).
  6. 目标代码优化:目标代码优化器(Target Code Optimizer)。

三.汇编阶段

汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中,hello.o是一个二进制文件。

四.链接阶段

hello程序调用了printf函数,它存在于一个名为printf.o的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到我们的hello.o程序中。连接器(ld)就负责处理这种合并。结果就得到了hello文件,它是一个可执行目标文件(或者称为可执行文件),可以被加载到内存中,由系统执行。(链接程序运行需要的一大堆目标文件,以及所依赖的其它库文件,最后生成可执行文件)。

  • 25
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

叶孤程

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

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

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

打赏作者

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

抵扣说明:

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

余额充值