2015-11-30 11 views
0

我在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 

而这个区域最终置入开始在与可执行区域的大小地址0x20000000一个RAM区域说,在分散文件0x400

当我到调试器我看到,在存储器地址0x0值为0x20000118这是初始堆栈指针和甚至寄存器窗口显示msp寄存器作为0x20000118

但我的理解是,堆栈的开始是从0x20000100因为这是上面的代码片断在做什么。

我无法从那里是这些额外0x18个字节来获得。

另外,我刚关闭microlib中模式,现在我看到初始堆栈指针是0x20000120
再次,从这些额外的0x20字节偏移量来自堆栈指针。

为什么不能叠加从那里我希望它是(0x20000100)开始,而不是一些额外的补偿?

回答

0

不,这段代码不会说初始堆栈指针会在0x20000100。

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

初始堆栈指针值将由链接器脚本(通常)计算。您还需要查看向量表的源代码(在大多数情况下,它将位于名为startup.s或类似文件的文件中),并查看哪些符号用作第一个条目(是否真的是“__initial_sp”?)。如果你有(例如)32KB的RAM,并且你的RAM从0x20000000开始,那么你想(通常)你的初始SP在0x20008000(RAM的末尾)。如果“堆栈大小”等于“0x100”,则表示您不希望SP小于0x20007F00。但是,您也可以在取决于其他节的大小(例如.heap或.data)的地址处具有初始堆栈指针。这就是为什么你可以看到链接到标准库时的差异(它会改变其他部分的大小)。