c语言的编译分为4个过程,分别是预处理,编译,汇编,链接。
一、预处理
预处理是c语言编译的第一个阶段,该任务主要由预处理器完成。预处理器会根据预处理指令对源代码进行处理,将预处理指令替换为相应的内容,然后生成编译所需的代码。预处理的主要作用是进行一些常用的文本替换和条件编译,从而提高代码的灵活性和可维护性。
预处理指令以井号(#)开头,包括宏定义、条件编译和包含文件等。
预处理的操作如下图所示,分别对main.c 和 hello.c 进行预处理,生成main.i 和 hello.i 文件。
二、编译
编译是将经过预处理器处理后的代码转换为汇编代码或者目标代码的过程,这个过程主要包括了词法分析、语法分析、语义分析和代码生成等步骤,由编译器完成。
编译的操作如下图所示,分别对main.i 和 hello.i 进行预处理,生成main.s 和 hello.s 文件。
三、汇编
汇编是将编译器生成的中间代码或者汇编语言转化为目标代码,即二进制形式。这个过程由汇编器完成。主要任务有:符号解析、指令翻译、地址关联、重定位、代码优化。
汇编的操作如下图所示,分别对main.s 和 hello.s 进行预处理,生成main.o 和 hello.o 文件。
四、链接
链接阶段主要是链接器将目标文件以及可能用到的库文件进行链接,生成最终可执行程序。主要有符号解析、符号重定位、代码段和数据段合并等操作。
链接的方式有三种,静态链接,动态链接和混合链接。
静态链接是将所有目标文件和所需的所有库一并打包到最终的可执行文件,使其在运行时不需要查找或加载外部库。
动态链接是在可执行文件包含需要i加载的库的路径与符号信息,在运行的时候才被加载。
混合链接是将部分函数库以静态链接的方式链接到可执行文件中,而另一部分则以动态链接的方式链接到可执行文件中。
如下图为静态链接生成的可执行文件 main 与动态链接生成的可执行文件 main1 。可以看出静态链接生成的文件大小远大于动态链接生成的文件,但静态链接的文件的执行速度却大于动态链接的文件。