C程序编译过程
2015-06-01 17:13
260 查看
gcc编译C代码会有四个阶段:
预处理:将C代码中的头文件和宏进行处理
编译:把预处理好的c代码生成与机器相关的as汇编代码 .s
汇编:把汇编代码转化成机器指令,并以特定的二进制格式输出保存在 .o这样的目标文件中
链接:链接指定的动态库,把与程序相关的文件组合链接在一起,生成可执行的映像文件。
流程图:
参考阅读:http://blog.csdn.net/zzxian/article/details/16820035
3. c程序分析
gcc -E hello.c -o hello.i //预处理
gcc -S hello.i -o hello.s //编译
gcc -c hello.s -o hello2.o //汇编
gcc hello.o -o hello //链接
Attention:直接输出就使用 gcc -S hello.i -o - 即可,加优化选项就是-O1
readelf -h hello.o //可以查看目标文件头文件的内容, 定义在"/usr/include/linux/elf.h"
objdump -h hello.o //命令只是显示关键段,省略了辅助性的段。”readelf -S”命令显示的更完整
readelf -S hello.o //命令可以显示所有段(bss data text)的内容
nm -A hello.o //可以显示所有变量在哪个区域
weiwei@weiwei-ubuntu:~/tools$ nm -A hello2.o
hello2.o:0000000000000004 C aaaaa
hello2.o:0000000000000000 b bbbbb
hello2.o:0000000000000008 b ddddd.2061
hello2.o:0000000000000004 C eeeaaaaa
hello2.o:0000000000000004 b eeeebbb
hello2.o:0000000000000028 C exec1
hello2.o:0000000000000000 T main
hello2.o: U printf
hello2.o: U puts
第二列:指明符号值(地址)
第三列:符号类型:b--->bss c--->common t--->test(所有的可以见Linux 内核完全剖析 P71)
第四列:对应的符号名称
int aaa = 1;
const int bbb = 1;
int ccc;
const int ddd;
int eee = 0;
const int fff = 0;
a.out:0000000000601020 D aaa
a.out:00000000004005fc R bbb
a.out:0000000000601040 B ccc
a.out:000000000060103c B ddd
a.out:0000000000601038 B eee
a.out:0000000000400600 R fff
全局变量:
B--->bss bss是指那些没有初始化的和初始化为0的全局变量,bss类型的全局变量只占运行时的内存空间,而不占文件空间
R---->rodata ro代表read only,即只读数据(const),运行时直接读取ROM内存,无需要加载到RAM内存中
D--->data data指那些初始化过(非零)的非const的全局变量。data类型的全局变量是即占文件空间,又占用运行时内存空间的
预处理:将C代码中的头文件和宏进行处理
编译:把预处理好的c代码生成与机器相关的as汇编代码 .s
汇编:把汇编代码转化成机器指令,并以特定的二进制格式输出保存在 .o这样的目标文件中
链接:链接指定的动态库,把与程序相关的文件组合链接在一起,生成可执行的映像文件。
流程图:
参考阅读:http://blog.csdn.net/zzxian/article/details/16820035
3. c程序分析
gcc -E hello.c -o hello.i //预处理
gcc -S hello.i -o hello.s //编译
gcc -c hello.s -o hello2.o //汇编
gcc hello.o -o hello //链接
Attention:直接输出就使用 gcc -S hello.i -o - 即可,加优化选项就是-O1
readelf -h hello.o //可以查看目标文件头文件的内容, 定义在"/usr/include/linux/elf.h"
objdump -h hello.o //命令只是显示关键段,省略了辅助性的段。”readelf -S”命令显示的更完整
readelf -S hello.o //命令可以显示所有段(bss data text)的内容
nm -A hello.o //可以显示所有变量在哪个区域
weiwei@weiwei-ubuntu:~/tools$ nm -A hello2.o
hello2.o:0000000000000004 C aaaaa
hello2.o:0000000000000000 b bbbbb
hello2.o:0000000000000008 b ddddd.2061
hello2.o:0000000000000004 C eeeaaaaa
hello2.o:0000000000000004 b eeeebbb
hello2.o:0000000000000028 C exec1
hello2.o:0000000000000000 T main
hello2.o: U printf
hello2.o: U puts
第二列:指明符号值(地址)
第三列:符号类型:b--->bss c--->common t--->test(所有的可以见Linux 内核完全剖析 P71)
第四列:对应的符号名称
int aaa = 1;
const int bbb = 1;
int ccc;
const int ddd;
int eee = 0;
const int fff = 0;
a.out:0000000000601020 D aaa
a.out:00000000004005fc R bbb
a.out:0000000000601040 B ccc
a.out:000000000060103c B ddd
a.out:0000000000601038 B eee
a.out:0000000000400600 R fff
全局变量:
B--->bss bss是指那些没有初始化的和初始化为0的全局变量,bss类型的全局变量只占运行时的内存空间,而不占文件空间
R---->rodata ro代表read only,即只读数据(const),运行时直接读取ROM内存,无需要加载到RAM内存中
D--->data data指那些初始化过(非零)的非const的全局变量。data类型的全局变量是即占文件空间,又占用运行时内存空间的
相关文章推荐
- Android源码分析(一):android原生源码编译期间执行的流程
- linux kernel Makefile编译流程分析
- C++静态库与动态库详解与使用
- 程序的编译和链接
- C++ 预处理、编译、汇编、链接
- pkg-config工具包程序编译中的使用
- C语言之进程空间---进程空间、数据分布、函数压/出栈
- C/C++程序编译流程详解
- Linux 的启动流程
- vim与复制,删除,粘贴,块操作以及快速替换功能
- Winform开发实践
- Android-manifest详解
- 携程数据库安全事件原因分析
- opencv介绍
- 发布到AppStore时把项目打包成ipa
- linux学习笔记—通配符
- 利用apache的rewrite来代替javascript,实现pc和phone的终端判断和跳转
- linux open() 函数使用说明
- 整理得比较全面的MySQL优化参考
- 固态硬盘与传统的机械硬盘的比较