Recently,I learned that the .bss
segment store uninitialized data. However, when I try a small program as below and use size(1)
command in terminal, the .bss segment didn't change, even if I add some global variables. Do I misunderstand something?
jameschu@aspire-e5-573g:~$ cat test.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
jameschu@aspire-e5-573g:~$ gcc -c test.c
jameschu@aspire-e5-573g:~$ size test.o
text data bss dec hex filename
89 0 0 89 59 test.o
jameschu@aspire-e5-573g:~$ cat test.c
#include <stdio.h>
int a1;
int a2;
int a3;
int main(void)
{
printf("hello world\n");
return 0;
}
jameschu@aspire-e5-573g:~$ gcc -c test.c
jameschu@aspire-e5-573g:~$ size test.o
text data bss dec hex filename
89 0 0 89 59 test.o
The . bss section is used by the compiler for global and static variables. It is one of the default COFF sections that is used to reserve a specified amount of space in the memory map that can later be used for storing data. It is normally uninitialized.
What is the difference between the Data and BSS sections? BSS refers to uninitialized global and static objects and Data refers to initialized global and static objects. Both BSS and Data usually refer to RAM objects.
The initialized data segment contains global and static variables that are explicitly initialized. The values of these variables are read from the executable file when the program is loaded into memory. The uninitialized data segment contains global and static variables that are not explicitly initialized.
In computer programming, the block starting symbol (abbreviated to . bss or bss) is the portion of an object file, executable, or assembly language code that contains statically allocated variables that are declared but have not been assigned a value yet. It is often referred to as the "bss section" or "bss segment".
This is because the way global variables work.
The problem that is being solved is that it is possible to declare a global variable, without initializing it, in several .c
files and not getting a duplicate symbol error. That is, every global uninitialized declaration works like a weak declaration, that can be considered external
if no other declaration contains an initialization.
How it this implemented by the compiler? Easy:
bss
segment it will be added to the COMMON
segment.COMMON
variables with the same name and discard anyone that is already in other section. The remaining ones will be moved to the bss
of the executable.And that is why you don't see your variables in the bss
of the object file, but you do in the executable file.
You can check the contents of the object sections using a more modern alternative to size
, such as objdump -x
. And note how the variables are placed in *COM*
.
It is worth noting that if you declare your global variable as static
you are saying that the variable belongs to that compilation unit, so the COMMON
is not used and you get the behavior you expect:
int a;
int b;
static int c;
$ size test.o
text data bss dec hex filename
91 0 4 95 5f test.o
Initializing to 0
will get a similar result.
int a;
int b;
int c = 0;
$ size test.o
text data bss dec hex filename
91 0 4 95 5f test.o
However initializing to anything other than 0
will move that variable to data
:
int a;
int b = 1;
int c = 0;
$ size test.o
text data bss dec hex filename
91 4 4 99 5f test.o
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With