Search code examples
clinuxsizestorage-class-specifier

Why BSS segment is "16" by default?


As per my knowledge, segmentation for c program is:

        High address
|---------------------------|
|env/cmd line args vars     |
|---------------------------|
|      stack segment        |--> uninitialized auto vars
|---------------------------|
|---------------------------|
|---------------------------|
|      heap segment         |--> dynamic allocated memory
|---------------------------|
|      BSS segment          |--> uninitialized static/global vars
|---------------------------|
|      data segment         |--> initialized static/global vars
|---------------------------|
|      text segment         |--> initialized auto vars/exec instructions
|---------------------------|
        Low address

On my RHEL 5.4 64-bit machine, for below c program

#include <stdio.h>
int main()
{
}

when I do:

# size a.out
   text    data     bss     dec     hex filename
   1259     540      16    1815     717 a.out

I am unable to understand why is

bss=16

As I am not declaring/initializing any global/static vars?


Solution

  • It's worse on Windows with gcc:

    main.c:

    #include <stdio.h>
    
    int main( int argc, char* argv[] )
    {
        return 0;
    }
    

    compile:

    C:\>gcc main.c
    

    size:

    C:\>size a.exe
       text    data     bss     dec     hex filename
       6936    1580    1004    9520    2530 a.exe
    

    bss includes the whole linked executable and in this case various libraries are linked in which do use static c initialisation.

    Using -nostartfiles gets a much better result on windows. You can also try with -nostdlib and -nodefaultlibs

    compile:

    C:\>gcc -nostartfiles main.c
    

    size:

    C:\>size a.exe
       text    data     bss     dec     hex filename
        488     156      32     676     2a4 a.exe
    

    Remove all the libraries (including the c library) and you get an "executable" with exactly what you've compiled and a bss size of 0:

    main.c:

    #include <stdio.h>
    
    int _main( int argc, char* argv[] )
    {
        return 0;
    }
    

    compile:

    C:\>gcc -nostartfiles -nostdlib -nodefaultlibs main.c
    

    size:

    C:\>size a.exe
       text    data     bss     dec     hex filename
         28      20       0      48      30 a.exe
    

    The executable won't run however!