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.
重点补充道。因此,后者似乎是正确的。将角色转换为空*似乎毫无意义。