Search topics...
Build SystemsPipeline & Compilationfoundational

What's the difference between .data and .bss?

0 upvotes
Practice with AISoon
Study the fundamentals first — Build Systems topic page

Both hold global variables, but they serve different purposes and have different storage costs.

.data holds globals with non-zero initial values: int x = 42;. Those values must exist somewhere persistent (Flash) so they survive power-off, but the variables themselves must be writable (RAM). So .data has both a Load Memory Address in Flash (where the initial values are stored in the binary) and a Virtual Memory Address in RAM (where the variables live at runtime). The startup code copies the initial values from Flash to RAM as part of the boot chain. Cost: Flash for the initial values + RAM for the variables.

.bss holds uninitialized (or zero-initialized) globals: int y; or int z = 0;. The C standard guarantees these start as zero. Since zero is a single value, you don't need to store anything in Flash — the startup code just memsets the .bss region to zero in RAM. Cost: RAM only; zero Flash.

The practical implication for embedded: a 100 KB uninitialized buffer (uint8_t buf[102400];) costs zero Flash because it lives in .bss. The same buffer with = {0} may go in .data and cost 100 KB Flash for all-zero initial values. Always declare large buffers without initializers and let .bss zero-fill.

A related distinction is .rodataconst-qualified globals like string literals and lookup tables — which lives in Flash and is read directly by the CPU at runtime. Cost: Flash only, no RAM. Always const your large lookup tables; without it, they double-cost (Flash + RAM).

Source: Build Systems Q&A