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

时间:2021-10-28 22:02:46

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).

我正在使用ARM-GCC编译器,在Internet上发现了两个版本的startup_stm32f10x_cl。c文件(启动代码)。处理器为: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?

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

2 个解决方案

#1


5  

From ARM documentation for M3 cores instruction-set:

来自M3核心的ARM文档说明:

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

PUSH使用SP寄存器中的值- 4作为最高的内存地址

and

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

完成后,将SP寄存器更新为指向最低存储值的位置

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

因此,我的解释是SP的起点必须是最高地址的+4,即栈数组边界之后的地址。因此

(void *)&pulStack[STACK_SIZE]

(void *)&pulStack[STACK_SIZE]

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

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

#2


1  

My local copy of the ARMv7-M Architecture Reference Manual states:

我的ARMv7-M架构参考手册的本地副本:

There are thirteen general-purpose 32-bit registers, R0-R12, and an additional three 32-bit registers that have special names and usage models.

有13个通用32位寄存器、R0-R12和另外3个32位寄存器,它们具有特殊的名称和使用模型。

  • SP Stack pointer, used as a pointer to the active stack. For usage restrictions see Use of 0b1101 as a register specifier on page A5-154. This is preset to the top of the Main stack on reset. See The SP registers on page B1-623 for more information. SP is sometimes referred to as R13.
  • SP堆栈指针,用作指向活动堆栈的指针。对于使用限制,请参阅在A5-154页上使用0b1101作为注册说明符。这是在重置时预设到主堆栈的顶部。有关更多信息,请参见B1-623页上的SP寄存器。SP有时被称为R13。

Emphasis added. So, the latter seems correct. The cast to void * seems pointless.

重点补充道。因此,后者似乎是正确的。将角色转换为空*似乎毫无意义。

#1


5  

From ARM documentation for M3 cores instruction-set:

来自M3核心的ARM文档说明:

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

PUSH使用SP寄存器中的值- 4作为最高的内存地址

and

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

完成后,将SP寄存器更新为指向最低存储值的位置

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

因此,我的解释是SP的起点必须是最高地址的+4,即栈数组边界之后的地址。因此

(void *)&pulStack[STACK_SIZE]

(void *)&pulStack[STACK_SIZE]

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

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

#2


1  

My local copy of the ARMv7-M Architecture Reference Manual states:

我的ARMv7-M架构参考手册的本地副本:

There are thirteen general-purpose 32-bit registers, R0-R12, and an additional three 32-bit registers that have special names and usage models.

有13个通用32位寄存器、R0-R12和另外3个32位寄存器,它们具有特殊的名称和使用模型。

  • SP Stack pointer, used as a pointer to the active stack. For usage restrictions see Use of 0b1101 as a register specifier on page A5-154. This is preset to the top of the Main stack on reset. See The SP registers on page B1-623 for more information. SP is sometimes referred to as R13.
  • SP堆栈指针,用作指向活动堆栈的指针。对于使用限制,请参阅在A5-154页上使用0b1101作为注册说明符。这是在重置时预设到主堆栈的顶部。有关更多信息,请参见B1-623页上的SP寄存器。SP有时被称为R13。

Emphasis added. So, the latter seems correct. The cast to void * seems pointless.

重点补充道。因此,后者似乎是正确的。将角色转换为空*似乎毫无意义。