Confusion about the Purpose of ._user_heap_stack
I’ve been discovering the different views available in STM32Cube IDE and among them is the Build Analyzer view.
In this view I found a section in the RAM called ._user_heap_stack.
I searched for it in the linker script and found that it corresponds to the following section :
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
With
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
In Figure 1, one can see that the start address of the ._user_heap_stack is 0x2000 002C. This means that the last address of the stack should be 0x2000 002C + 200 + 400 = 0x2000 062C, with the 8 byte alignment that would make it 0x2000 0630.

To make sure my calculations are correct, I added a variable in the linker script (highlighted in yellow):
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
PROVIDE ( _euserheapstack = .);
} >RAM
I accessed its value via the debugger console and it did give me this address
p/x & _euserheapstack
$2 = 0x2000 0630
So our calculations are correct!
Now what I expect is that at the start of the program (main), the stack pointer would point to this address, i.e. 0x2000 0630.
However, I found that it points to 0x2000 A000 as shown in Figure 2 which is a screenshot from the debugger console.
I called other functions from main and I found that indeed the stack grows downwards from 0x2000A000. I opened the Memory Monitor view to verify that it is true, which you can see from Figure 3.

If we refer back to the build analyser view in Figure 1, we find that this corresponds to the last address of our RAM (start address is 0x2000 0000, size is 40KB = 0xA000, so end address is 0x2000 A000).
I took another look at the linker script and the startup code and found the lines that correspond to the initialization of the stack pointer:
- In linker file:
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
- In startup code:
Reset_Handler:
ldr sp, =_estack /* Atollic update: set stack pointer */
I am confused why the stack pointer is assigned to start at 0x2000 A000 which is the end of the RAM and not at 0x2000 0630 which is the end of the ._user_heap_stack section. Does anyone know the what’s purpose of this section if the stack is not stored there? If it is called ._user_heap_stack one expects that the stack grows downward in that section and not way past it to at the end of the RAM section….
For reference, I am using an STM32F303 Discovery board and STM32CubeIDE Version 2.1.1
