目录
引言
前言
在前期学习过程中一味的输入并没有对学习成果进行复盘整理,导致知识点是很碎片化的并没有很好的融会贯通起来,基于此,笔者结合其他参考资料,对已学过知识进行归纳总结加深印象。做一天博客裁缝~
正文
思考我们写的.c/.cpp这样的源文件是如何生成可执行文件进行执行的呢?
先放总结
由.c->可执行文件有以下四步骤:
- 预编译(预处理) .c->.i (中间文件Intermediate file)
- 编译 .i->.s (汇编代码文件Assembly file)
- 汇编 .s->.o (目标文件Object file)
- 链接 .o->可执行文件(Linux: .out,windows:.exe)
再来看每个过程的详细分析
1.预编译过程
由.c变成.i文件,.i文件是中间文件Intermediate file
在Linux内的命令为:
gcc -E main.c -o main.i
- gcc main.c 命令,执行完整的编译过程并输出名为 .out的可执行文件
- gcc main.c -o main 命令会产生一个名为“main”的输出文件
- gcc -E main.c -o main.i 对源文件 main.c 进行预处理操作,并将结果放在 main.i 文件中。如果不使用 -o 选项,那么将生成名为 main.i 的预处理文件。
预编译过程具体在做什么?
- 处理所有带‘#’的指令
- 删除所有的“#define”,并且展开所有的宏定义;
- 处理所有的条件预编译指令,“#if”、“#ifdef”、“#endif”等;
- 处理“#include”预编译指令,将被包含的文件插入到该预编译指令的位置;
- 保留所有的#pragma 编译器指令,因为编译器需要使用它们。
- 删除所有的注释;
- 添加行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错误和警告时显示行号;
2.编译过程
由.i变成.s文件,.s文件是汇编代码文件Assembly file
在Linux内的命令为:
gcc -S main.i -o main.s
编译过程具体在做什么?
词法分析、语法分析、语义分析,代码优化,汇总符号。
编译检查语法错误,运行阶段检查逻辑错误。
3.汇编过程
由.s变成.o文件,.o文件是目标文件Object file
在Linux内的命令为:
gcc -c main.s -o mian.o
汇编过程具体在做什么?
将汇编指令翻译成二进制格式,生成各个 section,生成符号表。
4.链接过程
.o变成可执行文件, 可执行文件在Linux内形式是 .out,windows系统内形式为.exe
在Linux内的命令为:
gcc -o main main.o
链接过程具体在做什么?
- 合并各个 section,调整 section 的起始位移和段大小,合并符号表,进行符号解析,给符号分配虚拟地址
- 符号重定位