初始堆栈指针不是从所需的偏移量开始的(额外的字节偏移来自哪里?)

时间:2015-11-30 06:35:13

标签: stack arm cortex-m3 keil

我在从Keil获取的Cortex-M3的启动文件中有以下示例代码(用Microlib编译)。

; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
                EXPORT  __initial_sp
Stack_Size      EQU     0x00000100

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

此区域最终放入RAM区域,从地址0x20000000开始,散布文件中可执行区域的大小为0x400

当我进入调试器时,我看到内存地址0x0的值是0x20000118,它是初始堆栈指针,甚至寄存器窗口显示msp寄存器为{ {1}}。

但我的理解是堆栈的开头来自0x20000118,因为这就是上面的代码片段所做的。

我无法从这些额外的0x20000100字节来自何处。

另外,我只是关闭Microlib模式,现在我看到初始堆栈指针是0x18
同样,这些额外的0x20000120字节偏移从哪里来到堆栈指针。

为什么堆栈不是从我想要的位置开始(0x20),而是有一些额外的偏移?

1 个答案:

答案 0 :(得分:0)

不,这段代码片段并没有说初始堆栈指针位于0x20000100。

首先,它是EXPORTs符号“__initial_sp”。这仅将此符号声明为“全局”(由其他文件访问)。接下来,将值0x100分配给符号“Stack_Size”。接下来的说明是创建虚拟“STACK”部分,其大小为“stack_size”。

初始堆栈指针值将(通常)由链接描述文件计算。您还需要查看向量表的源代码(在大多数情况下,它将位于名为 startup.s 或类似的文件中),并查看用作第一个条目的符号(它真的是“ __initial_sp“?)。

注意,如果你有(例如)32KB的RAM而你的RAM从0x20000000开始,那么你希望(通常)你的初始SP为0x20008000(RAM的结尾)。如果“堆栈大小”等于“0x100”,则表示您不希望SP小于0x20007F00。但是,您还可以在地址处具有初始堆栈指针,该指针取决于其他部分的大小(例如.heap或.data)。这就是您在链接到标准库时可以看到差异的原因(它将改变其他部分的大小)。