哪个是初始堆栈指针的正确值?

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

我正在使用 ARM-GCC 编译器,我在 Internet 上找到了 startup_stm32f10x_cl.c 文件(启动代码)的两个版本。处理器是:STM32F105RC(ARM Cortex M3)。

共同部分:

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

然后,第一个版本像这样启动向量 table:

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

而第二个版本是这样的:

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

所以,我的问题是:
哪一个是正确的堆栈指针初始化?

来自 M3 内核指令集的 ARM 文档:

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

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

所以,我的解释是SP的起点必须是最高地址的+4,即紧接在Stack数组边界之后的地址。 因此

(void *)&pulStack[STACK_SIZE]

看起来不错,因为该地址(虽然不是数组的一部分)永远不会被使用。