C语言——程序的编译+链接(linux+gcc实现过程)


前言

一个程序要运行,一定要经历四个步骤。依次是: 预处理、编译、汇编和链接。那么接下来就依次拆解这些过程来更好的理解程序是如何运行起来的。

首先简述一下各步骤的内容:

  • 预处理:展开头文件/宏替换/去掉注释/条件编译
  • 编译 :检查语法,生成汇编代码
  • 汇编:把汇编代码转成二进制机器码写入目标文件
  • 链接:链接各模块生成可执行程序

后面展开讨论————


一、预处理

1.预处理阶段的操作:

  1. 展开所有的宏定义,将#define删除
  2. 删除所有注释
  3. 保留所有的#pragma编译指令,因为编译器需要使用它们。
  4. 处理条件编译指令
  5. 处理#include预编译指令,将被包含的头文件插到该编译指令的位置
  6. 添加行号和文件标识名

1.预处理过程实现:

可以使用linux来实现预处理到链接的过程并观察

gcc指令的用法

-E选项:提示编译器执行完预处理就停下来,后边的编译、汇编、链接就先不执行了。
-S选项:提示编译器执行完编译就停下来,不去执行汇编和链接了。
-c选项:提示编译器执行完汇编就停下来。
使用 gcc 命令不跟任何的选项的话,会默认执行预处理、编译、汇编、链接这整个过程,如果程序没有错,就会得到一个可执行文件,默认为a.out,使用 -o + 文件名可定义生成可执行文件的名称。

一个简单的代码理解预处理

在这里插入图片描述
首先,编辑一个test.c文件,里面有注释,宏定义及预编译指令等,执行gcc -E test.c -o test.i,生成一个test.i文件。
在这里插入图片描述

观察发现,文件变成了900行左右,宏定义已经被替换掉了,注释等也已经删除。上面的部分即stdio.h包含的代码。

二、编译

1.编译阶段的操作:

编译过程是整个程序构建的核心部分,编译成功,会将源代码由文本形式转换成机器语言,编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析以及优化后生成相应的汇编代码文件。

2.编译过程的实现:

依然是上面的简单代码,针对生成的test.i文件执行gcc -S test.i -o test.s,生成一个test.s文件。
在这里插入图片描述
观察test.s文件,已经从之前的文本形式转换成汇编代码。

三、汇编

1.汇编阶段的操作:

汇编过程调用汇编器as来完成,是用于将汇编代码转换成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。

2.汇编过程的实现:

针对生成的test.s文件执行gcc -c test.s -o test.o,生成一个test.o文件。
在这里插入图片描述
文件将变成这样的只有机器才能看懂的语言啦。

四、链接

1.链接阶段的操作:

链接的主要内容就是将各个模块之间相互引用的部分正确的衔接起来。它的工作就是把一些指令对其他符号地址的引用加以修正。链接过程主要包括了地址和空间分配、符号决议和重定向。

2.链接过程的实现:

使用gcc test.o -o test指令,生成一个test文件
在这里插入图片描述
这就是链接后的文件,也是一个可执行程序,用./test执行
在这里插入图片描述
可以看到最终得到了答案。

猜你喜欢

转载自blog.csdn.net/weixin_47460769/article/details/113832389
今日推荐