2015-10-22 72 views
3

我正在使用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

只要它們都導致地址與可寫內存正確對齊,那麼除非您試圖從內存中擠出每個RAM的最後一個字節,否則它並不重要。 – Notlikethat

+0

@Notlikethat:所以,你說的是,在第二個版本中有4個字節(未使用)。在這種情況下是否可能(通常)有某種安全防護存儲區? –

+0

我不會說它裏面有太多的安全性(這個例子可能只是一個人不確定一個堆棧推動是後減量還是預減量),但是沒有什麼可以阻止你在上面有一些固定的全局存儲區域堆棧如果你真的想要,或者開始堆棧和堆在RAM中間增長遠離其他Itanium風格,或其他任何;) – Notlikethat

回答

5

從M3芯指令集ARM文檔:

PUSH使用在SP寄存器減去4爲最高 存儲器地址的值

在完成,PUSH更新SP寄存器以指向存儲值最低的位置

所以,我的理解是,SP的起點必須是最高地址的+4,即緊接在堆棧數組邊界之後的地址。 因此

(無效*)& pulStack [STACK_SIZE]

看起來正確,因爲該地址(陣列的雖然不是部分),將永遠不會被使用。

+0

什麼是數組'pulStack'? –

+1

它的名字是匈牙利符號(在谷歌上檢查它)的一個數組持有無符號長整數...它可以被看作是一個指向無符號長向量(p u l)的指針。它僅僅是內存佔位符,就是編譯器用來存儲堆棧的那種「這個空間已被佔用」的定義。 – jpinto3912

+0

謝謝@ jpinto3912 –

1

我參考ARMv7-M架構參考手冊狀態的本地副本:

至少有13個通用32位寄存器R0-R12,並具有特殊的 另外3個32位寄存器名稱和用法 模型。

  • SP堆棧指針,用作指向活動堆棧的指針。有關 的使用限制,請參閱使用0b1101作爲寄存器說明符(第 A5-154)。這是預置爲重置上主堆棧的頂部。有關更多信息,請參閱第B1-623頁上的 SP寄存器。 SP有時被稱爲R13,即 。

強調添加。所以,後者似乎是正確的。投到void *似乎毫無意義。