C编程笔录(一)1.2: C编程的源文件到可执行程序文件的编译过程

C编程的源文件到可执行程序文件的编译过程可分解为四个步骤:预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)、链接(Linking)。

下面以示例解释这四个步骤,在Linux操作系统下以gcc命令编译main.c源文件到生成main.out可执行文件:

Linux系统版本:Linux version 3.10.0-514.6.2.el7.x86_64 

gcc版本:gcc version 4.8.5

测试源文件:main.c文件,文件内容如下编辑:

#include

int main(void)

{

    printf("hello world!");

    return 0;

}

执行gcc -o main.out main.c命令即可生成可执行文件main.out,这条命令执行的编译过程依次进行了预处理、编译、汇编和链接四个步骤,gcc也提供了相关命令生成对应步骤的目标文件,gcc -E命令可生成预处理后的源文件,-S生成编译处理后的源文件,-c或者-as生成汇编处理后的源文件,直接列出.o文件加-o指令加文件路径可生成链接处理后的可执行文件。

“预处理”过程:

1.处理所有条件编译指令,如:#ifndef、#ifdef、或者#if等。

2.处理所有文件包含指令,如:#include ,预处理器会将stdio.h文件内容插入到该指令位置。

3.删除所有注释代码,如"//"和"/*...*/"。

4.添加文件标识和行号,以便后续代码编译或调试时错误或警告信息提供行号或文件标识。

例:gcc -E main.c -o main.i

“编译”过程:

将“预处理”过的文件进行词法分析,扫描器将文件的字符序列分割成一系列的记号(Token),然后语法分析器将记号产生语法树(Syntax Tree),接着进行静态(在编译时可以确定的语义)和动态(在运行时可以确定的语义)语义分析,继而源代码优化,源代码优化器把整个语法树转化为中间代码(Intermediate Code),中间代码又使得编译器分别为前端和后端,前端编译器负责生成与机器码无关的中间代码,后端编译负责将中间代码转化为机器码。

例:gcc -S main.i -o main.s

“汇编”过程:

根据汇编指令和机器指令的对照表,将“编译”生成的中间代码转化为目标机器码,其过程其实就是一一对应翻译。

例:gcc -c main.s -o main.o

“链接”过程:

将“汇编”处理后的目标文件、以及这些文件所依赖的其他库文件串联起来生成可执行文件。其内容就是把各模块之间相互引用的部分处理好,使模块之间可以正确的衔接起来。链接有分静态和动态,静态链接是指在“编译”阶段把静态库一起加入编译,最后生成的可执行文件大小相比动态链接要大,动态链接是指源文件内加一些文件加载描述信息,在“链接”阶段不进行动态库加载,程序执行时再从系统中把动态库加载到内存中。

例:gcc main.o -o main.out


你可能感兴趣的:(C)