C程序的编译链接

2019-07-19  本文已影响0人  今天不想掉头发

C程序大体上分成预处理、编译、汇编和链接4个阶段。汇编器主要是根据汇编源代码中的section或者segment关键字,将对应的section和segment编译成节,生成目标文件,目标文件中的这些节还不是程序空间中独立的代码段或数据段,或者说仅仅是代码段或数据段的一部分。链接器将这些目标文件中属性相同的节合并成段,因此一个段是由多个节组成的,我们平时所说的C程序内存空间中的数据段、代码段就是指合并后的segment。
之所以将section合并成segment,一是为了保护模式下的安全检查,二是为了操作系统在加载程序时省事

因为保护模式下对内存的访问需要经过段描述符,段描述符是由选择子来决定的,选择子由操作系统提供,因此对于程序中不同属性的区域,操作系统得知道用哪个段描述符来匹配程序中这些不同属性的区域片段,也就是要在程序运行之前设置好各种段寄存器(ds、cs)中的选择子。

所以操作系统必须知道程序中的这些节的属性是什么,以便加载程序的时候为其分配不同的段选择子,从而使程序内存指向不同的段描述符。所以链接器最好将目标文件中属性相同的节合并到一起,这样操作系统便可以统一分配内存。

按照属性来分配节,大致有3种:
1.可读写的数据,如数据节.data和未初始化节.bss
2.可读可执行的代码,如代码节.text和初始化代码节.init
3.只读数据,如只读数据节.rodata,一般情况下字符串就存储在此节
所有节都可以归并到以上三种之一,然后链接器将相同属性的节归并之后的节的集合,就叫做segment,它存在于二进制可执行文件之中,也就是C程序运行时内存空间中分布的代码段、数据段等段。

对于bss段,存储的是未初始化的全局变量和局部静态变量,是不占用文件系统空间的数量,仅存在于内存中,bss的作用仅仅是为了程序运行过程中使用的未初始化数据变量提前预留了内存空间。

上一篇 下一篇

猜你喜欢

热点阅读