猿问

为什么需要.bss段?

我知道的是,全局变量和静态变量存储在.data段中,而未初始化的数据存储在.bss段中。我不明白的是,为什么我们有专用于未初始化变量的段?如果未初始化的变量在运行时分配了值,那么该变量是否.bss仅仍存在于段中?


在以下程序中,  a在.data段中,并且b在.bss段中;那是对的吗?如果我的理解是错误的,请纠正我。


#include <stdio.h>

#include <stdlib.h>


int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9};

int b[20]; /* Uninitialized, so in the .bss and will not occupy space for 20 * sizeof (int) */


int main ()

{

   ;

}  

另外,请考虑以下程序,


#include <stdio.h>

#include <stdlib.h>

int var[10];  /* Uninitialized so in .bss */

int main ()

{

   var[0] = 20  /* **Initialized, where this 'var' will be ?** */

}


慕村225694
浏览 1753回答 3
3回答

jeck猫

原因是减小程序大小。想象一下,您的C程序在嵌入式系统上运行,其中代码和所有常量都保存在真正的ROM(闪存)中。在这样的系统中,必须在调用main()之前执行初始的“ copy-down”以设置所有静态存储持续时间对象。通常将如下所示:for(i=0; i<all_explicitly_initialized_objects; i++){&nbsp; .data[i] = init_value[i];}memset(.bss,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;0,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;all_implicitly_initialized_objects);.data和.bss存储在RAM中,而init_value存储在ROM中。如果它是一个段,则ROM必须填充很多零,从而显着增加ROM的大小。尽管基于RAM的可执行文件没有真正的ROM,但它们的工作原理类似。同样,memset可能是一些非常有效的内联汇编程序,这意味着可以更快地执行启动复制。

森林海

该.bss细分是一种优化。整个.bss段用一个数字描述,可能是4个字节或8个字节,该数字给出了运行过程中它的大小,而该.data部分则与初始化变量的大小之和一样大。因此,这.bss使得可执行文件更小,加载更快。否则,变量可能位于.data显式初始化为零的段中;该程序很难分辨出差异。(详细来说,其中的对象地址.bss可能与该.data段中的地址不同。)在第一个程序,a将在.data链段和b将在.bss可执行文件的段。加载程序后,区别就不再重要了。在运行时,b占用20 * sizeof(int)字节。在第二个程序中,var分配了空间,并且分配main()修改了该空间。碰巧的var是,.bss段中描述的空间而不是.data段中描述的空间,但这并不影响程序在运行时的行为方式。

富国沪深

从汇编语言步骤分步:使用Linux编程杰夫Duntemann,有关。数据部分:本。数据部分包含初始化的数据项的数据定义。初始化数据是在程序开始运行之前具有值的数据。这些值是可执行文件的一部分。当将可执行文件加载到内存中以供执行时,它们会加载到内存中。关于.data节要记住的重要一点是,您定义的初始化数据项越多,可执行文件将越大,并且在运行它时将其从磁盘加载到内存所需的时间也越长。和.bss部分:在程序开始运行之前,并非所有数据项都需要具有值。例如,当您从磁盘文件中读取数据时,需要有一个放置数据的位置,以便将数据从磁盘中导入。程序的.bss部分中定义了类似的数据缓冲区。您为缓冲区留出了一定数量的字节,并为缓冲区指定了名称,但是您没有说缓冲区中将出现什么值。.data节中定义的数据项与.bss节中定义的数据项之间存在至关重要的区别:.data节中的数据项增加了可执行文件的大小。.bss部分中的数据项没有。可以在.bss中定义一个占用16,000字节(或更多,有时更多的字节)的缓冲区,并且几乎不增加任何内容(描述中大约50字节)。
随时随地看视频慕课网APP
我要回答