从编译到可运行文件

我们的平时写的代码是经过怎样的过成变成让计算机可执行的文件。下面我给出了一个大致的流程:

源代码经过预编译,编译,汇编,链接过程到可执行的exe文件。

其实我们的代码就产生了两种东西,一种是数据一种是指令。

数据和指令可定不能杂乱的放在一起,系统会将我们的数据和指令进行分区,那具体的划分区域是什么和划分的根据?

程序跑起来后,不会直接把数据直接搞到物理内存上,因为操作系统要屏蔽底层的差异,统一管理资源的分配。因此系统会先给每个程序一个虚拟地址空间,每个虚拟地址空间的大小为4个G即2^32,每个程序都会有,因为是虚拟的。不是占用你的实际内存,所以不用担心内存够不够用的问题。

虚拟地址空间配分的示意图

编译和链接

首先整个4G空间被划分2个部分,一个部分为用户空间,大小为3个G,地址从0x00000000-0xC00000000另一个部分为内核空间,大小为1G,地址从0xC0000000-0XFFFFFFFF;其中用户空间每个程序都是独立的,每个程序都有自己的3G虚拟地址空间的用户空间。而内核空间却是共享的。因为里面操作系统就只有一个,一些系统运行的状态,数据等必须统一,如果独立的话就乱套了。.txt段就是代码段,正文段,存放我们程序指令代码的地方。.bss段和.data段就是存放数据的地方。 
而数据段也分为data段和bss段。bss段全名better save space 更加节省空间。 因此我们就把那些定义初值为0的,或者没有给初值的都放在.bss段 .bss段是不占用文件空间的。他只是记录了有几个bss的数据,反正值都是0。有必要开辟几块4个字节整形 去存放我已知的0?注意这里bss节省的空间指的是节省文件的空间,虚拟地址空间还是占用的。而那些初值不为0的数据,我就必须要记录下数据究竟是什么,因此要放到data段。是实际占空间的。

了解完程序在内存中的划分我们看看程序的编译过程:

1.预编译

扫描二维码关注公众号,回复: 4126202 查看本文章

删除代码中的注释,处理预编译中的头文件最后生成 .i文件。

2.编译

词法分析,语法分析,语义分析,所有符号的汇总  , 代码的优化,最后生成  .s文件。

3.汇编

经行汇编将代码翻译成二进制形式,生成 .o 和.obj文件。

4.链接

1.合并编译后生成的所有***.obj文件的段 调整段长度

   合并符号表,解析符号   

   解析完后就要分配内存地址了,因为每个.o文件的地址之前说了都是独立,可能相同的。你我的偏移量完全可能相同。因此就要分配内存地址,避免冲突

2.符号的重定位最终生成可执行的.exe文件。

猜你喜欢

转载自blog.csdn.net/qq_41896615/article/details/83796155