程序的编译、链接过程(内存布局)

一个C程序经过编译、链接生成可执行文件,一个运行着的可执行文件,我们称之为进程,要了解程序的编译链接,首先要知道进程在内存上的布局,即虚拟地址空间。

我们的操作系统(32位)为每个可执行程序分配4G的虚拟空间,其中3G用户空间,1G内核空间。

如下为进程的虚拟地址空间

程序的编译、链接过程(内存布局)

.text :代码段

.data:数据段(存放已初始化且初始化不为0的静态局部变量和全局变量)

.bss:数据段(存放未初始化或初始化为0的静态局部变量和全局变量)

heap:堆区(malloc或new申请的内存)

stakc:栈区(存放局部变量)

argc,envi:命令行参数及环境变量

最后就是内核空间。

接下来就是编译链接过程

预编译:宏替换,头文件的展开,去掉注释。

编译:代码的优化,符号汇总,生成汇编语言代码。

汇编:根据对应关系将汇编指令转成本地操作系统机器码。

生成可重定位文件(目标文件):划分代码段、数据段、符号表。

链接:所有的.o文件的段进行合并,其中包含符号表,进行符号解析,解析正确后,给符号表的符号分配虚拟地址;进行符号重定向(将编译时生成指令中的地址替换成正确的虚拟地址)。

在编译过程中,相应指令中的地址是无效的,要在链接后进行符号解析及符号重定向将其改成正确的虚拟地址。