堆栈指针在STM32F103上如何工作

问题描述 投票:0回答:2

我最近对 MCU 的链接描述文件和汇编编码感兴趣。我刚刚发现我们在reset_handler中做的第一件事是设置堆栈指针寄存器(sp)。

我的问题是:ST的所有教程和示例代码都显示RAM末尾的_estack变量,即0x20005000。然而,flash是从0x08000000开始的,而我编译的ELF文件的向量表是在flash的开头(0x08000000),但是我们将堆栈指针设置为_estack(0x20005000),这不是flash的开头。然而,代码是有效的。

如何让堆栈指针指向0x20005000,而指令从0x08000000(向量表)开始,并且仍然有效?

我的基本链接器:

_estack = 0x20005000;

MEMORY
{
    FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 64K
    RAM (rxw)       : ORIGIN = 0x20000000, LENGTH = 20K
}

我的程序集文件reset_handler(相关部分):

.type reset_handler, %function
reset_handler:
    LDR     r0, =_estack
    MOV     sp, r0
c assembly linker embedded mcu
2个回答
0
投票

您需要阅读文档。

  1. 当处理器启动时,堆栈指针被分配向量表中偏移量
    0
    处的值。如果从 FLASH 启动,它将位于以下地址
    0x08000000
    。向量表中的下一个位置是 ResetHandler 地址,处理器从存储在那里的地址开始执行

指令从0x08000000(向量表)开始,并且它 还有效吗?

不,说明不是从那里开始的。向量表只是处理程序的地址数组 - 第一个是初始堆栈指针,第二个是重置处理程序的地址。

_estack
只是符号,重置处理程序中的指令将其值加载到堆栈指针中。


0
投票

堆栈通常(但并非总是)放置在 RAM 的末尾,并且它们向下增长。

STM32F103 有 20 KiB RAM,位于 [

0x20'000'000
,
0x20'004'fff
] 之间。

0x20'005'000
实际上不是一个有效的地址。在压入堆栈操作期间,硬件会先递减堆栈指针,然后再将压入的值放入 RAM。

© www.soinside.com 2019 - 2024. All rights reserved.