Memory Layout of Embedded C Program Explained Simply
text for code, data for initialized variables, bss for uninitialized variables, heap for dynamic memory, and stack for function calls and local variables. This layout helps the microcontroller organize and manage memory efficiently during program execution.How It Works
Imagine your embedded device's memory as a house with different rooms, each serving a special purpose. The text section is like the living room where all the instructions (code) live. This area is read-only and contains the program's compiled code.
The data section is like a pantry stocked with initialized ingredients (variables with set values). The bss section is an empty storage room reserved for variables that start with no value but will be used later.
The heap is a flexible space where you can request extra storage during runtime, like renting a storage locker when you need more space. The stack is a temporary workspace where function calls and local variables are kept, similar to a desk where you work on tasks one at a time.
Example
This simple embedded C program shows variables in different memory sections and prints their addresses to illustrate the layout.
#include <stdio.h> #include <stdlib.h> int initialized_global = 10; // Goes to data section int uninitialized_global; // Goes to bss section int main() { static int static_var = 5; // Data section int local_var = 3; // Stack int *dynamic_var = malloc(sizeof(int)); // Heap *dynamic_var = 7; printf("Address of code (main): %p\n", (void*)main); printf("Address of initialized_global: %p\n", (void*)&initialized_global); printf("Address of uninitialized_global: %p\n", (void*)&uninitialized_global); printf("Address of static_var: %p\n", (void*)&static_var); printf("Address of local_var: %p\n", (void*)&local_var); printf("Address of dynamic_var (heap): %p\n", (void*)dynamic_var); free(dynamic_var); return 0; }
When to Use
Understanding the memory layout is crucial when programming embedded systems because these devices have limited memory and strict performance needs. Knowing where variables and code reside helps you optimize memory use and avoid errors like stack overflow or heap fragmentation.
For example, in real-time systems like automotive controllers or medical devices, placing critical code in the text section ensures it runs reliably. Using the stack carefully prevents crashes, and managing the heap wisely avoids memory leaks.
Key Points
- Text section: stores program code, read-only.
- Data section: holds initialized global and static variables.
- BSS section: holds uninitialized global and static variables.
- Heap: dynamic memory allocated at runtime.
- Stack: stores local variables and function call info.