Search code examples
cgccinitializationstackarm

Which one is the correct value for the initial stack pointer?


I am using ARM-GCC compiler and I found on Internet two versions for the startup_stm32f10x_cl.c file (startup code). The processor is: STM32F105RC (ARM Cortex M3).

Common part :

#define STACK_SIZE       0x100 /*!< The Stack size */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];    

Then, the first version starts the vector table like this:

void (* const g_pfnVectors[])(void) =
{       
  (void *)&pulStack[STACK_SIZE],     /*!< The initial stack pointer           */
  Reset_Handler,                /*!< Reset Handler                            */
...

while the second version looks like this:

void (* const g_pfnVectors[])(void) =
{       
  (void *)&pulStack[STACK_SIZE - 1],     /*!< The initial stack pointer           */
  Reset_Handler,                /*!< Reset Handler                            */
    ...

So, my question is:
Which one is the correct stack pointer initialization?


Solution

  • From ARM documentation for M3 cores instruction-set:

    PUSH uses the value in the SP register minus four as the highest memory address

    and

    On completion, PUSH updates the SP register to point to the location of the lowest stored value

    So, my interpretation is that the starting point of SP must be +4 of the highest address, i.e. the address immediately after the Stack array bounds. Hence

    (void *)&pulStack[STACK_SIZE]
    

    looks right, as that address (although not part of the array), will never be used.