March 17, 2005

Confusion about BSS section in DLL/EXEs

Yesterday there was a question in microsoft.public.de.vc about the using of the BSS section in an app with global initialized data. Normally BSS is only used to store uninitialized data. Here is a short example:

  int Val0=0;
  int Val1=1;
  void main() {}

If you compile this with “cl /Fa” you will get the following assembler output (in short):

  _BSS SEGMENT

?Val0@@3HA DD01H DUP (?); Val0 _BSS ENDS _DATA SEGMENT ?Val1@@3HA DD01H; Val1 _DATA ENDS

And here you see the problem: Val0 is initialized in the C source code but it seems that it will not be initialized because it is stored in the “uninitialized data” (BSS) section!!! Very confusing, ins´t it?

An other problem is that there is no direct documentation about this behaviour; there are only two references, which leads to the result, that sections with “uninitialized data” (IMAGE_SCN_CNT_UNINITIALIZED_DATA) are always initialized to zero!

First reference: Initializing Scalar Types
If you do not explicitly initialize a global static variable, it is initialized to 0 by default, and every member that has pointer type is assigned a null pointer.

Second reference: Peering Inside the PE: A Tour of the Win32 Portable Executable File Format
The .bss section is where any uninitialized static and global variables are stored.

But I missed some docu about the fact that “uninitialized” only means: The space must not be reserved in the EXE/DLL but the section is always initialized to zero (I also look into the PE-COFF spec but yould not find it either). Maybe someone has a link to this kind of clarification?


Posted 2 years, 10 months ago on March 17, 2005
The trackback url for this post is http://blog.kalmbachnet.de/bblog/trackback.php/33/

Re: Confusion about BSS section in DLL/EXEs
It's not confusing, but it is a bit subtle. Uninitialized sections are not initialized, even though they may appear to be. The memory pages reserved for uninitialized sections will be cleared (set to all zero bits) by the operating system at some point before they are committed. MSVC relies on this operating system behaviour and the fact that cleared memory will give the exact same result as zero initialization would. It's usually an optimization because you get smaller executables that will load slightly faster (no need to store store or load data that's just filled with zero).
Posted 2 years, 9 months ago by Johan Petersson • • wwwReply
Comment Trackback URL : http://blog.kalmbachnet.de/bblog/trackback.php/33/59/

Comments have now been turned off for this post