我正在使用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];
然后,第一个版本启动矢量表,如下所示:
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 */
...
所以,我的问题是:
哪一个是正确的堆栈指针初始化?
答案 0 :(得分:5)
来自M3核心指令集的ARM文档:
PUSH使用SP寄存器中的值减去4作为最高值 记忆地址
和
完成后,PUSH更新SP寄存器以指向该位置 最低储值
所以,我的解释是SP的起点必须是最高地址的+4,即紧接在Stack数组边界之后的地址。 因此
(void *)&amp; pulStack [STACK_SIZE]
看起来正确,因为该地址(尽管不是数组的一部分)永远不会被使用。
答案 1 :(得分:1)
我的ARMv7-M架构参考手册的本地副本声明:
有13个通用32位寄存器,R0-R12和a 另外三个具有特殊名称和用法的32位寄存器 模型。
- SP 堆栈指针,用作指向活动堆栈的指针。对于 使用限制请参阅第0页的使用0b1101作为寄存器说明符 A5-154。这是预设为重置时主堆栈的顶部。见 有关更多信息,请在第B1-623页注册SP。 SP有时候 简称R13。
重点补充。所以,后者似乎是正确的。演员void *
似乎毫无意义。