我在从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
),而是有一些额外的偏移?
答案 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)。这就是您在链接到标准库时可以看到差异的原因(它将改变其他部分的大小)。