【转】(深⼊理解计算机系统)bss段,data段、text段、堆
(heap)和栈(stack)
bss段:
  bss段(bss segment)通常是指⽤来存放程序中未初始化的全局变量的⼀块内存区域。
  bss是英⽂Block Started by Symbol的简称。
  bss段属于静态内存分配。
data段:
  数据段(data segment)通常是指⽤来存放程序中已初始化的全局变量的⼀块内存区域。
  数据段属于静态内存分配。
text段:
  代码段(code segment/text segment)通常是指⽤来存放程序执⾏代码的⼀块内存区域。
  这部分区域的⼤⼩在程序运⾏前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。
  在代码段中,也有可能包含⼀些只读的常数变量,例如字符串常量等。
堆(heap):
  堆是⽤于存放进程运⾏中被动态分配的内存段,它的⼤⼩并不固定,可动态扩张或缩减。
  当进程调⽤malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);
  当利⽤free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。
栈(stack):
  栈⼜称堆栈,是⽤户存放程序临时创建的局部变量,
  也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。
  除此以外,在函数被调⽤时,其参数也会被压⼊发起调⽤的进程栈中,并且待到调⽤结束后,函数的
返回值也会被存放回栈中。  由于栈的先进先出(FIFO)特点,所以栈特别⽅便⽤来保存/恢复调⽤现场。
  从这个意义上讲,我们可以把堆栈看成⼀个寄存、交换临时数据的内存区。
⼀个程序本质上都是由 bss段、data段、text段三个组成的。
  这样的概念,不知道最初来源于哪⾥的规定,但在当前的计算机程序设计中是很重要的⼀个基本概念。
  ⽽且在嵌⼊式系统的设计中也⾮常重要,牵涉到嵌⼊式系统运⾏时的内存⼤⼩分配,存储单元占⽤空间⼤⼩的问题。
在采⽤段式内存管理的架构中(⽐如intel的80x86系统),bss段通常是指⽤来存放程序中未初始化的全局变量的⼀块内存区域,
  ⼀般在初始化时bss 段部分将会清零。bss段属于静态内存分配,即程序⼀开始就将其清零了。
⽐如,在C语⾔之类的程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的全局变量保存在.bss 段中。
  text和data段都在可执⾏⽂件中(在嵌⼊式系统⾥⼀般是固化在镜像⽂件中),由系统从可执⾏⽂件中加载;
  ⽽bss段不在可执⾏⽂件中,由系统初始化。
【例】
两个⼩程序如下:
程序1:
int ar[30000];
void main()
{
......
}
程序2:
int ar[300000] = {1, 2, 3, 4, 5, 6 };
void main()
{
......
}
发现程序2编译之后所得的.exe⽂件⽐程序1的要⼤得多。当下甚为不解,于是⼿⼯编译了⼀下,并使⽤了/FAs编译选项来查看了⼀下其各⾃的.asm,
发现在程序1.asm中ar的定义如下:
_BSS SEGMENT
ar@@3PAHA DD 0493e0H DUP ()  ; ar
_BSS ENDS
⽽在程序2.asm中,ar被定义为:
_DATA SEGMENT
ar@@3PAHA DD 01H  ; ar
DD 02H
DD 03H
ORG $+1199988
_DATA ENDS
区别很明显,⼀个位于.bss段,⽽另⼀个位于.data段,两者的区别在于:
全局的未初始化变量存在于.bss段中,具体体现为⼀个占位符;
全局的已初始化变量存于.data段中;
⽽函数内的⾃动变量都在栈上分配空间;
.bss是不占⽤.exe⽂件空间的,其内容由操作系统初始化(清零);
.
data却需要占⽤,其内容由程序初始化。因此造成了上述情况。
bss段(未⼿动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的⼤⼩;
bss段的⼤⼩从可执⾏⽂件中得到,然后链接器得到这个⼤⼩的内存块,紧跟在数据段后⾯。
字符串常量存放在哪个内存区域
data段(已⼿动初始化的数据)则为数据分配空间,数据保存在⽬标⽂件中;
data段包含经过初始化的全局变量以及它们的值。当这个内存区进⼊程序的地址空间后全部清零。
包含data段和bss段的整个区段此时通常称为数据区。
【】

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。