1.GCC背后的故事
(一)准备工作
我们先打开Ubuntu系统,用mkdir命令创建一个新的文件夹来存放程序文件。然后通过vim命令编写一个简单的c语言程序文件helloworld.c。
(二)编译过程
1.预处理
预处理过程的完整流程:
- 字符集转换:处理源代码的字符编码
- 续行符处理:将反斜杠换行符连接为单行
- 注释删除:移除所有注释
- 宏展开:展开所有宏定义
- 条件编译:处理条件编译指令
- 头文件包含:插入包含的文件内容
- 特殊标记:添加行号和文件名信息
- 输出结果:生成预处理后的文本文件
通过预处理,原始的C源代码被转换为不包含预处理指令的纯C代码,为后续的编译阶段做好准备。
使用gcc进行预处理的命令如下:
2.编译
预处理之后的编译阶段时将预处理生成的.i文件转换为汇编代码的过程。这是整个汇编过程的核心阶段。其主要任务为词法分析,语法分析,语义分析,中间代码生成,代码优化以及最后生成目标代码。
具体通过gcc命令实现该操作如下:
通过上述命令生成的汇编代码如下所示:
3.汇编
汇编阶段是将汇编代码转换为机器可执行的二进制目标代码的过程。这是将人类可读的汇编语言翻译成机器指令的关键步骤。汇编阶段的主要任务为指令翻译,符号解析,地址分配。
通过gcc命令实现汇编的操作如下:
或者可以使用as命令进行汇编操作:
4.链接
链接阶段是将多个目标文件(.o)和库文件组合成一个可执行文件或库文件的过程。这是编译过程的最后一步,解决了符号引用和地址重定位问题。链接阶段的主要任务为符号解析(解析所有未定义的符号引用),地址重定位(为代码和数据分配最终的内存地址),库链接(链接所需的静态库和动态库)。链接阶段完成后,就生成了可以直接在操作系统上运行的可执行文件。
使用特定的gcc命令可以链接动态库生成可执行文件,生成的ELF可执行文件的大小和链接的动态库如下所示:
使用特定的gcc命令可以链接静态库生成可执行文件,生成的ELF可执行文件的大小和链接的静态库如下所示:
(三)分析ELF文件