程序执行过程发生了什么
- 预处理(Preprocessing):
预处理包括宏替换、条件编译、文件包含、去除注释等工作。 此时产生的是 .i文件,这是一个文本文件。
linux生成预处理文件命令:
gcc -E test.c -o test.i
上述命令中-E是让编译器在预处理之后就退出,不进行后续编译过程;-o是指定输出文件名。在本例中,预处理结果就是将stdio.h 文件中的内容插入到test.c中了。
- 编译(Compilation):
这个过程将产生 .s文件。这里的编译指的是将 .i文件变成 .s文件之间的过程 ,所以这个过程是将源代码编译成汇编代码的过程。
和 .i文件一样:
gcc -S test.i -o test.s
指定生成 .s文件
编译分为几个阶段:
- 词法分析:编译器将源代码分解成一个个词法单元,用于识别词法
- 语法分析:此时根据词法分析构建抽象语法树,作用是检查此时的语法结构是否符合编程语言的语法规则,并将其转化成一个树形结构用于分析转换。
图来源:原po
- 汇编(Assembly):
这一步产生的文件是 .o文件,是将汇编代码转换成机器码(二进制格式)的过程。
gcc -c test.s -o test.o
- 链接(Linking):
这一步是将 .o文件转换成可执行文件的过程。
gcc test.o -o test
链接是将多个目标代码文件和库文件组合在一起,形成最终的可执行文件的过程。链接器会解析目标代码文件中的符号引用(如函数调用),并将其与相应的符号定义进行关联。链接器还会执行符号重定位操作,确保不同代码模块之间的地址引用是正确的。最终,链接器将所有的代码和数据段组合在一起,生成可执行文件。
此外,链接器还可以处理其他任务,如符号表的生成、优化和修复等。链接将多个模块整合成可执行文件,使得程序能够在计算机上运行。
总结起来,预处理、编译、汇编和链接是将高级语言源代码转换为可执行文件的关键步骤。它们在不同的阶段对源代码进行处理和转换,以便最终生成可以在计算机上运行的二进制代码。