16 C語言及ARM中堆疊指標SP設定的理解與總結

2021-08-22 12:58:38 字數 1923 閱讀 9320

棧是一種特殊的線性表,是一種只允許在表的一端進行插入或刪除操作的線性表。表中允許進行插入、刪除操作的一端稱為棧頂。表的另一端稱為棧底。棧頂的當前位置是動態的,對棧頂當前位置的標記稱為棧頂指標。當棧中沒有資料元素時,稱之為空棧。棧的插入操作通常稱為進棧或入棧,棧的刪除操作通常稱為退棧或出棧。

簡易理解:

客棧,即臨時寄存的地方,計算機中的堆疊主要用來儲存臨時資料,區域性變數和中斷/呼叫子程式程式的返回位址。程式中棧主要是用來儲存函式中的區域性變數以及儲存暫存器引數的,如果你用了作業系統,棧中還可能儲存當前進執行緒的上下文。設定棧大小的乙個原則是,保證棧不會下溢位到資料空間或程式空間.cpu在執行程式時,會自動的使用堆疊,所以堆疊指標sp就必須要在呼叫c程式前設定。

cpu的記憶體ram空間存放規律一般是分段的,從位址向高位址,依次為:程式段(.text),bss段,然後上面還可能會有堆空間,然後最上面才是堆疊段,這樣安排堆疊,是因為堆疊的特點決定的,所以堆疊的指標sp初始化一般在堆疊段的高位址,也就是記憶體的高位址,然後讓堆疊指標向下增長(其實就是遞減)。這樣做的好處就是堆疊空間遠離了其他段,不會跟其他段重疊,造成修改其他段資料,而引起不可預料的後果,還有設定堆疊大小的原則,要保證棧不會下溢位到資料空間或者程式空間。所謂堆疊溢位,是指堆疊指標sp向下增長到其他段空間,如果棧指標向下增長到其他段空間,稱為堆疊溢位。堆疊溢位會修改其他空間的值,嚴重情況下可造成宕機.

開始將堆疊指標設定在內部ram,是因為不是每個板上都有外部ram,而且外部ram的大小也不相同,而且如果是sdram,還需要初始化,在內部ram開始執行的一般是乙個小的引導程式,基本上不怎麼使用堆疊,因此將堆疊設定在內部ram,但這也就要去改引導程式不能隨意使用大量區域性變數。

片內4k的sram,sdram大小64m,從0x30000000到0x33ffffff,當程式在片內sram執行的時候,sp的值設定為4096,當程式在sdram內執行的時候sp設定為0x34000000,當然當程式在內部sram執行,若已經初始化sdram,此時也可以將堆疊指標設定為0x34000000,更加防止了堆疊溢位。

1) 儲存現場;

2) 傳遞引數:彙編**呼叫 c 函式時,需傳遞引數;

3) 儲存臨時變數:包括函式的非靜態區域性變數以及編譯器自動生成的其他臨時變數;

1)  儲存現場

現場,意思就相當於案發現場,總有一些現場的情況,要記錄下來的,否則被別人破壞掉之後,你就無法恢復現場了。而此處說的現場,就是指 cpu 執行的時候,用到了一些暫存器,比如 r0,r1 等等,對於這些暫存器的值,如果你不儲存而直接跳轉到子函式中去執行,那麼很可能就被其破壞了,因為其函式執行也要用到這些暫存器。因此,在函式呼叫之前,應該將這些暫存器等現場,暫時保持起來(入棧 push),等呼叫函式執行完畢返回後(出棧 pop),再恢復現場。這樣cpu就可以正確的繼續執行了。儲存暫存器的值,一般用的是 push 指令,將對應的某些暫存器的值,乙個個放到棧中,把對應的值壓入到棧裡面,即所謂的壓棧。然後待被呼叫的子函式執行完畢的時候,再呼叫 pop,把棧中的乙個個的值,賦值給對應的那些你剛開始壓棧時用到的暫存器,把對應的值從棧中彈出去,即所謂的出棧。其中儲存的暫存器中,也包括 lr 的值(因為用 bl 指令進行跳轉的話,那麼之前的 pc 的值是存在 lr 中的),然後在子程式執行完畢的時候,再把棧中的 lr 的值 pop 出來,賦值給 pc,這樣就實現了子函式的正確的返回

2)  傳遞引數

c 語言進行函式呼叫的時候,常常會傳遞給被呼叫的函式一些引數,對於這些 c 語言級別的引數,被編譯器翻譯成組合語言的時候,就要找個地方存放一下,並且讓被呼叫的函式能夠訪問,否則就沒發實現傳遞引數了。對於找個地方放一下,分兩種情況。一種情況是,本身傳遞的引數不多於 4 個,就可以通過暫存器 r0~r3 傳送引數。因為在前面的儲存現場的動作中,已經儲存好了對應的暫存器的值,那麼此時,這些暫存器就是空閒的,可以供我們使用的了,那就可以放引數。另一種情況是,引數多於 4 個時,暫存器不夠用,就得用棧了。

3)  臨時變數儲存在棧中

包括函式的非靜態區域性變數以及編譯器自動生成的其他臨時變數。

16 C語言 指標

學習 c 語言的指標既簡單又有趣。通過指標,可以簡化一些 c 程式設計任務的執行,還有一些任務,如動態記憶體分配,沒有指標是無法執行的。include int main 當上面的 被編譯和執行時,它會產生下列結果 通過上面的例項,我們了解了什麼是記憶體位址以及如何訪問它。接下來讓我們看看什麼是指標。...

16 C 中的this指標

在之前學習python時,接觸到self形參,它是指向類物件的乙個位址。在c 學習過程中,也有這樣的機制,那就是this指標。我們在呼叫成員函式的時候,實際上是替類的物件呼叫它!成員函式通過乙個名為this的額外的隱式引數來訪問呼叫它的那個物件!當我們呼叫成員函式的時候,用請求的該函式的物件的位址來...

C語言及ARM中堆疊指標SP設定的理解與總結

棧是一種特殊的線性表,是一種只允許在表的一端進行插入或刪除操作的線性表。表中允許進行插入 刪除操作的一端稱為棧頂。表的另一端稱為棧底。棧頂的當前位置是動態的,對棧頂當前位置的標記稱為棧頂指標。當棧中沒有資料元素時,稱之為空棧。棧的插入操作通常稱為進棧或入棧,棧的刪除操作通常稱為退棧或出棧。簡易理解 ...