回顾一下编译链接的过程:
一、
#include
int main()
{
printf('hello world ');
return 0;
}
预编译:gcc -E hello.c -o hello.i
1.进行文本替换 如头文件,#开头的宏定义 #if #ifdef 等
2.删除注释
3.添加行号,以便编译时需要产生行号方便调试
4.保留#pragma,因为编译器要用
最终得到的.i文件,实际上还是一个文本文件
编译:gcc -S hello.i -o hello.s
1.词法分析,语法分析
2.语义分析并进行优化
得到汇编代码,还是一种文本文件,mov,add类似文件,cpu还是不能识别
汇编:gcc hello.c -o hello.o
得到可重定位的二进制文件,不可执行,因为符号、数据以及指令的地址都是无效的
链接:gcc -static -o main a.o
b.o
这里是静态链接
1.符号的重定位
2.合并多个.o文件相同属性的节,如text data等
多个.o文件将被整合到同一虚拟地址空间
链接优点:
1.各个模块分别编译,可以提高效率
2.模块代码可以复用
3.无需包含整个共享库的代码,只需将需要的部分调用即可
一、
#include
int main()
{
}
预编译:gcc -E hello.c
1.进行文本替换
2.删除注释
3.添加行号,以便编译时需要产生行号方便调试
4.保留#pragma,因为编译器要用
最终得到的.i文件,实际上还是一个文本文件
编译:gcc -S
1.词法分析,语法分析
2.语义分析并进行优化
得到汇编代码,还是一种文本文件,mov,add类似文件,cpu还是不能识别
汇编:gcc
得到可重定位的二进制文件,不可执行,因为符号、数据以及指令的地址都是无效的
链接:gcc
这里是静态链接
1.符号的重定位
2.合并多个.o文件相同属性的节,如text
链接优点:
1.各个模块分别编译,可以提高效率
2.模块代码可以复用
3.无需包含整个共享库的代码,只需将需要的部分调用即可
