Therefore, by default, the compiler puts both zero-initialized and
uninitialized data into the same data section, which is populated with zeroes at runtime by
the C library initialization code. The data section can either be a RW data section (.data)
or a ZI data section (.bss). When optimizing, the compiler might put small global ZI data
items in RW data sections. Specifying --bss_threshold=0
prevents this behavior, and puts small global ZI data items in
ZI data sections.
You can prevent uninitialized data from being initialized to zero by placing that data in a
different section. This can be achieved using #pragma arm section
, or with
the GNU compiler extension
__attribute__((section("name
")))
.
The following example shows how to keep uninitialized data using #pragma arm section
:
#pragma arm section zidata = "non_initialized"
int i, j; // uninitialized data in non_initialized section (without the pragma,
// would be in .bss section by default)
#pragma arm section zidata // back to default (.bss section)
int k = 0, l = 0; // zero-initialized data in .bss section
Specify --bss_threshold=0
when
compiling this example code, to ensure that k
and l
are placed in a ZI data section. If --bss_threshold=0
is not used, section name rwdata
must be used
instead of zidata
.
The non_initialized
section is placed into
its own UNINIT
execution region, as follows:
LOAD_1 0x0
{
EXEC_1 +0
{
* (+RO)
* (+RW)
* (+ZI) ; ZI data gets initialized to zero
}
EXEC_2 +0 UNINIT
{
* (non_initialized) ; ZI data does not get initialized to zero
}
}