关于BSS段的大小

1.BSS段中的内容

先明确 BSS 段“存放”的是未初始化的全局变量与局部静态变量,此处指的存放是指为其预留空间(占位符)。但BSS段在磁盘上不是真的占用变量大小的空间,它仅是在该段中记录了所有未初始化全局变量与局部静态变量的大小总和,至于每个变量的大小则存储在符号表的size属性中。即:

BSS段内容:无内容,它将在段表中占一个段描述符,该段描述符的size属性将记录未初始化的全局变量与局部静态变量的大小总和

每个未初始化全局对象与静态对象的大小:存储在符号表的 size 属性中

(上述说法求证于C++牛人“蓝色”,表感谢。。。)


注:段表描述了ELF各个段的信息,比如每个段的段名,长度,在文件中的偏移等。ELF文件的段结构就是由段表决定的。

注:段表的结构是一个以“Elf32_shdr”结构体为元素的数组,数组元素个人等于段的数目,每一个结构体对应一个段。将这个结构体称为段描述符。而BSS则仅在段表中占用一个段描述符。但是在实际的ELF文件中不存在该段。


2.BSS段在加载运行前的处理

当可执行文件加载运行前,会为BSS段中的变量分配足够的空间并全部自动清理(因此,才有未初始化的全局变量的值为0的说法)。


3.BSS段的作用

BSS段主要是为了节省可执行文件在磁盘上所占的空间,其仅仅记录变量所需的大小。对未初始化的大型数组的节省效率比较明显。举例如下:

static int a[10000];
int main()
{
     //...
}

在上述程序中,若不存在 BSS 段,则可执行文件将开辟一个 10000 * sizeof(int) 大小的空间,并全部存储为0,int 为4字节的情况下,该变量将在磁盘上占用39KB的空间。但是此时若是存在BSS 段,则在可执行文件中,将只是记录现在的BSS段总大小为40000即可,而无需真正的占据39KB的空间

该可执行文件在执行前将重新开辟39KB的空间,并自动初始化为0


4. 代码优化对BSS段的影响

考虑以下两个静态变量分别存储在哪个段中:

static int x1 = 1;
static int x2 = 0;

很明显可以看出,X1将被发在.data段中。令人意外的是 X2 将被放置在 .bss 段中,因为 x2 的值为0,被认为是未初始化的,因此将会被放在 .bss 段中以节省磁盘空间。


5.Linux 下查看段属性的指令:

用readelf -s 或 objdump -t 查看符号表
用readelf -S 或 objdump -h 查看段表

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值