8

I wrote the simple C program (test.c) below:-

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

and executed the follwing to understand size changes in .bss segment.

gcc test.c -o test
size test

The output came out as:-

   text    data     bss     dec     hex filename
   1115     552       8    1675     68b test

I didn't declare anything globally or of static scope. So please explain why the bss segment size is of 8 bytes.

I made the following change:-

#include<stdio.h>
int x;    //declared global variable
int main()
{
   return 0;
}

But to my surprise, the output was same as previous:-

   text    data     bss     dec     hex filename
   1115     552       8    1675     68b test

Please explain. I then initialized the global:-

#include<stdio.h>
int x=67;    //initialized global variable
int main()
{
   return 0;
}

The data segment size increased as expected, but I didn't expect the size of bss segment to reduce to 4 (on the contrary to 8 when nothing was declared). Please explain.

text       data     bss     dec     hex filename
1115        556       4    1675     68b test

I also tried the comands objdump, and nm, but they too showed variable x occupying .bss (in 2nd case). However, no change in bss size is shown upon size command.

I followed the procedure according to: http://codingfox.com/10-7-memory-segments-code-data-bss/ where the outputs are coming perfectly as expected.

Maharshi Roy
  • 358
  • 2
  • 11

2 Answers2

7

When you compile a simple main program you are also linking startup code. This code is responsible, among other things, to init bss.

That code is the code that "uses" 8 bytes you are seeing in .bss section.

You can strip that code using -nostartfiles gcc option:

-nostartfiles

Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used

To make a test use the following code

#include<stdio.h>

int _start()
{
   return 0;
}

and compile it with

gcc -nostartfiles test.c

Youll see .bss set to 0

   text    data     bss     dec     hex filename
    206     224       0     430     1ae test
Community
  • 1
  • 1
LPs
  • 16,045
  • 8
  • 30
  • 61
  • Hi, I tried the same using -nostartfiles flag, but the executable when run giving **Hello world segmentation fault (code dumped)**! How is that? Also, when I compile with **gcc -Wall -nostartfiles 1test.c**, it gives: **/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008048230**. Given my program: `#include int main(){ printf("Hello world\n"); return 0; }` – Dr. Essen Mar 15 '18 at 07:39
  • @Ac3_DeXt3R As the warning says: if you remove standard start files with **-nostartfiles** you must provide a `_start` function that will be the entry point of your code. – LPs Mar 15 '18 at 08:20
2

Your first two snippets are identical since you aren't using the variable x.

Try this

#include<stdio.h>
volatile int x;
int main()
{
   x = 1;
   return 0;
}

and you should see a change in .bss size.

Please note that those 4/8 bytes are something inside the start-up code. What it is and why it varies in size isn't possible to tell without digging into all the details of mentioned start-up code.

Lundin
  • 195,001
  • 40
  • 254
  • 396