快速理解 .bss、.data和.rodata

来源:互联网 发布:任务网站源码 编辑:程序博客网 时间:2024/05/17 04:32

全局变量是放在全局内存中的,用static修饰的局部变量也是会放在放全局内存的,它的作用域是局部的,但生命期是全局的

全局强调的是它的生命期,而不是它的作用域,所以有时可能把两者的概念互换。一般来说,在一起定义的两个全局变量,在内存的中位置是相邻的。这是一个简单的常识,但有时挺有用,如果一个全局变量被破坏了,不防先查查其前后相关变量的访问代码,看看是否存在越界访问的可能。

在ELF格式的可执行文件中,全局内存包括三种:bssdatarodata

1.bss是指那些没有初始化的和初始化为0的全局变量。

#include <stdio.h>int a = 0x77778888;int b = 0;int main(){    return 0;}

处理结果:

[root@localhost huge12]# gcc -g -c section2.c 
[root@localhost huge12]# strip section2.o
[root@localhost huge12]# objdump -h section2.o
section2.o:     file format elf32-i386
Sections:
Idx Name          Size      VMA       LMA       File off  Algn

  0 .text         00000019  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000004  00000000  00000000  00000050  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000004  00000000  00000000  00000054  2**2
                  ALLOC

从运行结果:

1.bss 段不存放在程序文件中

2.由于 bss 段中的变量不需要初始化成特定值(0除外),所以不需要在程序文件中保存其内容,好处是能减小程序文件的大小而节省存储空间

2.data与bss相比,data就容易明白多了,它的名字就暗示着里面存放着数据。当然,如果数据全是零,为了优化考虑,编译器把它当作bss处理。通俗的说,data指那些初始化过(非零)的非const的全局变量。

从运行结果:

于 .data 段内数据的初始化,是引导加载器加载程序时,通过将程序文件中 .data 段的数据复制到所对应的内存地址空间,从而一次性地完成所有变量的初始化

3.rodata的意义同样明显,ro代表read only,即只读数据(const)。关于rodata类型的数据,要注意以下几点:

  • 常量不一定就放在rodata里,有的立即数直接编码在指令里,存放在代码段(.text)中。
  • 对于字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件(EXE/SO)中只存在一份拷贝。
  • rodata是在多个进程间是共享的,这可以提高空间利用率。
  • 在有的嵌入式系统中,rodata放在ROM(如norflash)里,运行时直接读取ROM内存,无需要加载到RAM内存中。


1 0
原创粉丝点击