Stack pointer initialization and heap bounds
The C library requires you to specify where the stack pointer begins. If you intend to use Arm^{®} library functions that use the heap, for example, malloc()
, calloc()
, or if you define argc
and argv
commandline arguments for main()
, the C library also requires you to specify which region of memory the heap is initially expected to use.
You must always specify where the stack pointer begins. The initial stack pointer must be aligned to a multiple of 8 bytes for AArch32 and a multiple of 16 bytes for AArch64.
You might have to configure the heap if, for example:
 You intend to use Arm library functions that use the heap, for example,
malloc()
,calloc()
.  You define
argc
andargv
commandline arguments formain()
If you are using the C library's initialization code, use any of the following methods to configure the stack and heap:
 Use the symbols
__initial_sp
,__heap_base
, and__heap_limit
.  Use a scatter file to define
ARM_LIB_STACKHEAP
,ARM_LIB_STACK
, orARM_LIB_HEAP
regions.  Implement
__user_setup_stackheap()
or__user_initial_stackheap()
.
Note
The first two methods are the only methods that microlib supports for defining where the stack pointer starts and for defining the heap bounds.If you are not using the C library's initialization code (see Building an application without the C library), use the following method to configure the stack and heap:
 Set up the stack pointer manually at your application's entry point.
 Call
_init_alloc()
to set up an initial heap region, and implement__rt_heap_extend()
if you need to add memory to it later.
Configuring the stack and heap with symbols
Define the symbol __initial_sp
to point to the
top of the stack.
If using the heap, also define symbols __heap_base
and __heap_limit
.
You can define these symbols in an assembly language file.
For example:
__attribute__((naked)) void dummy_function(void) { __asm(".global __initial_sp\n\t" ".global __heap_base\n\t" ".global __heap_limit\n\t" ".equ __initial_sp, STACK_BASE\n\t" ".equ __heap_base, HEAP_BASE\n\t" ".equ __heap_limit, (HEAP_BASE+HEAP_SIZE)\n\t" ); }
The constants STACK_BASE
, HEAP_BASE
and HEAP_SIZE
can
be defined in a header file, for example stack.h,
as follows:
/* stack.h */ #define HEAP_BASE 0x20100000 /* Example memory addresses */ #define STACK_BASE 0x20200000 #define HEAP_SIZE ((STACK_BASEHEAP_BASE)/2) #define STACK_SIZE ((STACK_BASEHEAP_BASE)/2)
Note
This method of specifying the initial stack pointer and heap bounds is supported by both the standard C library (standardlib) and the micro C library (microlib).Configuring the stack and heap with a scatter file
In a scatter file, either:

Define
ARM_LIB_STACK
andARM_LIB_HEAP
regions.If you do not intend to use the heap, only define an
ARM_LIB_STACK
region. Define an
ARM_LIB_STACKHEAP
region.If you define an
ARM_LIB_STACKHEAP
region, the stack starts at the top of that region. The heap starts at the bottom.
Configuring the stack and heap with __user_setup_stackheap()
Implement __user_setup_stackheap()
to
set up the stack pointer and return the bounds of the initial heap region.
Configuring the heap from bare machine C using _init_alloc and __rt_heap_extend
If you are using a heap implementation from bare machine C
(that is an application that does not
define main()
and does not initialize the C library) you must define the base and top of the heap as well as providing a heap extension function.
Call
_init_alloc(
to define the base and top of the memory you want to manage as a heap.base
,top
)Note
The parameters of_init_alloc(
must be eightbyte aligned.base
,top
)Define the function
unsigned __rt_heap_extend(
to handle calls to extend the heap when it becomes full.unsigned
size,void
**block)
Stack and heap collision detection
By default, if memory allocated for the heap is
destined to overlap with memory that lies in close proximity with the stack, the potential
collision of heap and stack is automatically detected and the requested heap allocation
fails. If you do not require this automatic collision detection, you can save a small amount
of code size by disabling it with __asm(".global
__use_two_region_memory\n\t")
.
Note
The memory allocation functions (malloc()
, realloc()
, calloc()
, posix_memalign()
) attempt to detect
allocations that collide with the current stack pointer. Such detection
cannot be guaranteed to always be successful.Although it is possible to automatically detect expansion of the heap into the stack, it is not possible to automatically detect expansion of the stack into heap memory.
For legacy purposes, it is possible for you to bypass all of these methods and behavior. You can do this by defining the following functions to perform your own stack and heap memory management:
__rt_stackheap_init()
__rt_heap_extend()
Extending heap size at runtime
To enable the heap to extend into areas of memory other than
the region of memory that is specified when the program starts,
you can redefine the function __user_heap_extend()
.
__user_heap_extend()
returns blocks of
memory for heap usage in extending the size of the heap.