Linux(程序设计):01---程序编译原理(预处理、汇编、编译、链接)
一、程序编译原理
1.程序编译一般分为四个步骤,最后生成一个可执行的文件
- 第一步(预处理):在程序运行(main函数执行)之前,修改源码,主要处理代码中的#include头文件和#define宏定义代码(将程序运行时用到的#include头文件中的代码和#define宏定义的代码进行替换),最后生成一个.i文件(.i文件里面是替换代码之后的代码文件)
- 第二步(汇编):此阶段会检查代码的规范性、是否有语法错误等。在检查无误后,把.i代码文件进行编译,然后生成一个汇编语言.s文件(.s文件里面都是汇编语言)。此处只进行编译生成汇编代码,而不真正的进行汇编
- 第三步(编译):此阶段把.s文件翻译成二进制机器指令.o文件。生成的.o文件是二进制文件(直接用文本工具打开看到的将是乱码,我们需要反汇编工具如GDB的帮助才能读懂它),Windows下为.obj文件
- 第四步(链接):此阶段会链接所有的函数、全局变量,将所有的.o文件链接成一个可执行文件(例如hello.c文件调用了printf函数,printf函数存在一个名为printf.o的文件中,而我们必须把printf.o合并到hello.o中)。不过有时.o文件太多,链接会很不方便,所以我们会给.o文件进行打包生成静/动态库文件(Windows下为.lib和.dll文件,Linux下为.a和.so文件)
2.注意事项
- ①在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但仍可以生成Object File。但是链接时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码
- ②一个.c文件只生成一个.i和.s和.o文件,链接时是将所有的.o文件一起链接
- ③.h文件不直接参与源码编译,.cpp/.c等参与源码编译
- ④承上,因为.h文件不参与源码编译,所以在.h文件中不要写带内存的代码
二、各种后缀名文件的意义
- .c:C语言源代码文件
- .h:是程序所包含的头文件
- .i :预处理过的C源代码文件
- .s:是汇编语言源代码文件
- .o:是汇编之后的目标文件
- .S:是经过预编译的汇编语言源代码文件
三、演示案例
将一个hello.c文件进行预处理、编译、汇编、链接
- 第一步:预处理
.i文件内容为:将.c里面用到的#include和宏定义的代码替换之后的代码文件
gcc -E -o hello.i hello.c
- 第二步:编译
.s里面是汇编语言
gcc -S -o hello.s hello.i
- 第三步:汇编
编译生成一个二进制文件
gcc -c -o hello.o hello.s
- 第四步:链接
链接生成一个可执行文件
gcc -o hello hello.o
- 第五步:执行生成的hello可执行文件,打印出内容
./hello