Linux 为什么需要 .bss 段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9535250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is the .bss segment required?
提问by Whoami
What I know is that global and static variables are stored in the .data
segment, and uninitialized data are in the .bss
segment. What I don't understand is why do we have dedicated segment for uninitialized variables? If an uninitialised variable has a value assigned at run time, does the variable exist still in the .bss
segment only?
我所知道的是,全局和静态变量存储在.data
段中,未初始化的数据在.bss
段中。我不明白的是为什么我们有未初始化变量的专用段?如果未初始化的变量在运行时分配了值,该变量是否仅存在于.bss
段中?
In the following program, a
is in the .data
segment, and b
is in the .bss
segment; is that correct? Kindly correct me if my understanding is wrong.
在下面的程序中, 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 ()
{
;
}
Also, consider following program,
另外,请考虑以下程序,
#include <stdio.h>
#include <stdlib.h>
int var[10]; /* Uninitialized so in .bss */
int main ()
{
var[0] = 20 /* **Initialized, where this 'var' will be ?** */
}
采纳答案by Lundin
The reason is to reduce program size. Imagine that your C program runs on an embedded system, where the code and all constants are saved in true ROM (flash memory). In such systems, an initial "copy-down" must be executed to set all static storage duration objects, before main() is called. It will typically go like this pseudo:
原因是为了减少程序大小。想象一下,您的 C 程序运行在嵌入式系统上,其中代码和所有常量都保存在真正的 ROM(闪存)中。在此类系统中,在调用 main() 之前,必须执行初始“向下复制”以设置所有静态存储持续时间对象。它通常会像这个伪:
for(i=0; i<all_explicitly_initialized_objects; i++)
{
.data[i] = init_value[i];
}
memset(.bss,
0,
all_implicitly_initialized_objects);
Where .data and .bss are stored in RAM, but init_value is stored in ROM. If it had been one segment, then the ROM had to be filled up with a lot of zeroes, increasing ROM size significantly.
其中 .data 和 .bss 存储在 RAM 中,而 init_value 存储在 ROM 中。如果它是一个段,那么 ROM 必须填充很多零,从而显着增加 ROM 大小。
RAM-based executables work similarly, though of course they have no true ROM.
基于 RAM 的可执行文件的工作方式类似,尽管它们当然没有真正的 ROM。
Also, memset is likely some very efficient inline assembler, meaning that the startup copy-down can be executed faster.
此外,memset 可能是一些非常高效的内联汇编器,这意味着可以更快地执行启动复制。
回答by janneb
Well, first of all, those variables in your example aren't uninitialized; C specifies that static variables not otherwise initialized are initialized to 0.
好吧,首先,您示例中的那些变量并非未初始化;C 指定未以其他方式初始化的静态变量被初始化为 0。
So the reason for .bss is to have smaller executables, saving space and allowing faster loading of the program, as the loader can just allocate a bunch of zeroes instead of having to copy the data from disk.
所以 .bss 的原因是有更小的可执行文件,节省空间并允许更快地加载程序,因为加载程序可以只分配一堆零,而不必从磁盘复制数据。
When running the program, the program loader will load .data and .bss into memory. Writes into objects residing in .data or .bss thus only go to memory, they are not flushed to the binary on disk at any point.
运行程序时,程序加载器会将 .data 和 .bss 加载到内存中。写入驻留在 .data 或 .bss 中的对象因此只会进入内存,它们不会在任何时候刷新到磁盘上的二进制文件。
回答by Jonathan Leffler
The .bss
segment is an optimization. The entire .bss
segment is described by a single number, probably 4 bytes or 8 bytes, that gives its size in the running process, whereas the .data
section is as big as the sum of sizes of the initialized variables. Thus, the .bss
makes the executables smaller and quicker to load. Otherwise, the variables could be in the .data
segment with explicit initialization to zeroes; the program would be hard-pressed to tell the difference. (In detail, the address of the objects in .bss
would probably be different from the address if it was in the .data
segment.)
该.bss
段是一种优化。整个.bss
段由一个数字描述,可能是 4 个字节或 8 个字节,这给出了它在运行过程中的大小,而该.data
段与初始化变量的大小之和一样大。因此,这.bss
使得可执行文件更小,加载速度更快。否则,变量可能在.data
显式初始化为零的段中;该程序将很难区分。(详细地说,对象的地址.bss
可能与.data
段中的地址不同。)
In the first program, a
would be in the .data
segment and b
would be in the .bss
segment of the executable. Once the program is loaded, the distinction becomes immaterial. At run time, b
occupies 20 * sizeof(int)
bytes.
在第一个程序中,a
将在.data
段中,b
并将在.bss
可执行文件的段中。一旦程序被加载,区别就变得无关紧要了。在运行时,b
占用20 * sizeof(int)
字节。
In the second program, var
is allocated space and the assignment in main()
modifies that space. It so happens that the space for var
was described in the .bss
segment rather than the .data
segment, but that doesn't affect the way the program behaves when running.
在第二个程序中,var
分配了空间,并且赋值main()
修改了该空间。恰好var
在.bss
段中而不是在.data
段中描述了for 的空间,但这并不影响程序在运行时的行为方式。
回答by mihai
From Assembly Language Step-by-Step: Programming with Linuxby Jeff Duntemann, regarding the .datasection:
从汇编语言 Step-by-Step: Programming with Linuxby Jeff Duntemann,关于.data部分:
The .datasection contains data definitions of initialized data items. Initialized data is data that has a value before the program begins running. These values are part of the executable file. They are loaded into memory when the executable file is loaded into memory for execution.
The important thing to remember about the .data section is that the more initialized data items you define, the larger the executable file will be, and the longer it will take to load it from disk into memory when you run it.
本。数据部分包含初始化的数据项的数据定义。初始化数据是在程序开始运行之前具有值的数据。这些值是可执行文件的一部分。当可执行文件被加载到内存中执行时,它们被加载到内存中。
关于 .data 部分要记住的重要一点是,您定义的初始化数据项越多,可执行文件就越大,运行时将其从磁盘加载到内存中所需的时间也就越长。
and the .bsssection:
和.bss部分:
Not all data items need to have values before the program begins running. When you're reading data from a disk file, for example, you need to have a place for the data to go after it comes in from disk. Data buffers like that are defined in the .bsssection of your program. You set aside some number of bytes for a buffer and give the buffer a name, but you don't say what values are to be present in the buffer.
There's a crucial difference between data items defined in the .data section and data items defined in the .bss section: data items in the .data section add to the size of your executable file. Data items in the .bss section do not. A buffer that takes up 16,000 bytes (or more, sometimes much more) can be defined in .bss and add almost nothing (about 50 bytes for the description) to the executable file size.
在程序开始运行之前,并非所有数据项都需要有值。例如,当您从磁盘文件中读取数据时,您需要有一个地方让数据在从磁盘进入后存放。像这样的数据缓冲区在程序的.bss部分中定义。您为缓冲区留出一定数量的字节并为缓冲区命名,但您没有说明缓冲区中将出现哪些值。
.data 部分中定义的数据项与 .bss 部分中定义的数据项之间存在重要区别:.data 部分中的数据项会增加可执行文件的大小。.bss 部分中的数据项没有。可以在 .bss 中定义占用 16,000 字节(或更多,有时更多)的缓冲区,并且几乎不向可执行文件大小添加任何内容(大约 50 字节用于描述)。
回答by Philip Oakley
The wikipedia article .bssprovides a nice historical explanation, given that the term is from the mid-1950's (yippee my birthday;-).
维基百科文章.bss提供了一个很好的历史解释,因为该术语来自 1950 年代中期(yippee 我的生日;-)。
Back in the day, every bit was precious, so any method for signalling reserved empty space, was useful. This (.bss) is the one that has stuck.
回到过去,每一点都是宝贵的,因此任何表示保留空白空间的方法都是有用的。这个(.bss)是卡住的那个。
.datasections are for space that is not empty, rather it will have (your) defined values entered into it.
.data部分用于非空的空间,而是将(您的)定义的值输入其中。