【C语言】程序编译与链接
由我们所编写的源程序文件(文件后缀名为 .c)经过一系列的处理后,生成可执行文件(文件后缀名为**.exe**)
程序实现的过程中,电脑中存在两个环境:翻译环境(用于将源代码转换为机器指令) 和 运行环境(执行翻译生成的机器指令)
在翻译环境中将源代码翻译为机器指令的过程中,分为两大部分:> 编译 和 链接
在一个工程(solution)下,通常可能存在多个源程序文件,在编译过程中,各个源程序文件会单独被 编译器 编译为各个目标文件(文件后缀名为 .obj),各个目标文件会与 链接库(主要是各种库函数) 在 链接器 的处理下,生成一个完整的可执行程序
编译部分分为三大部分:> 预编译 编译 汇编
在VS中,可以通过使用 extern 的声明 来使用处于其他源文件中的函数;
预编译(又称为预处理)
/* 在Linux环境下 */
gcc test.c -E -o test.i
/* -E 表示只完成预处理,之后停止。 */
/* -o 即output 将生成的新内容放入 test.i 的文件中 */
在预编译阶段
#inlcude <stdio.h>
/* stdio.h文件中所有的代码都会被复制到test.c文件中 */
#include
#pragama
#define /* 符号替换在预处理阶段完成 */
/* 称为预处理指令,在预处理阶段执行该指令 */
删除注释:在预编译阶段会 被删除 或者 被替换为空格
预编译阶段的操作主要是 文本操作
编译
/* 在Linux环境下,对test.i进行处理 */
gcc test.i -S
/* -S 对经预处理的文件 进行 编译 操作,完成后停止 */
/* 会生成一个 test.s 的文件 */
将 C语言代码 转换为 汇编代码:
- 语法分析
- 词法分析
- 语义分析
- 符号汇总:主要对全局的符号(变量)进行汇总
汇编
/* 在Linux环境下,对test.s进行处理 */
gcc test.s -c
/* -c 对目标文件执行汇编操作 */
/* 会生成一个 test.o 的文件 */
/* .o后缀的文件即为目标文件 二进制文件 */
会将编译阶段生成的汇编代码转化成二进制指令
在符号汇总之后,在汇编阶段形成符号表
链接
在链接阶段会采取以下操作:
- 合并段表:Linux环境利用elf来组织文件,可以使用命令 readelf 来读取目标文件
- 符号表的重定位:将 函数声明中的符号地址 替换为 实际函数的符号地址