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

2021-08-18 08:41:00 字數 1788 閱讀 9648

什麼是棧:

簡易理解:

客棧,即臨時寄存的地方,計算機中的堆疊主要用來儲存臨時資料,區域性變數和中斷/呼叫子程式程式的返回位址。程式中棧主要是用來儲存函式中的區域性變數以及儲存暫存器引數的,如果你用了作業系統,棧中還可能儲存當前進執行緒的上下文。設定棧大小的乙個原則是,保證棧不會下溢位到資料空間或程式空間。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,更加防止了堆疊溢位。

棧的整體作用

a.儲存現場;

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

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

1)儲存現場:

現場,意思就相當於案發現場,總有一些現場的情況,要記錄下來的,否則被別人破壞掉之後,你就無法恢復現場了。而此處說的現場,就是指cpu執行的時候,用到了一些暫存器,比如r0,r1等等,對於這些暫存器的值,如果你不儲存而直接跳轉到子函式中去執行,那麼很可能就被其破壞了,因為其函式執行也要用到這些暫存器。因此,在函式呼叫之前,應該將這些暫存器等現場,暫時保持起來(入棧 push),等呼叫函式執行完畢返回後(出棧 pop),再恢復現場。這樣cpu就可以正確的繼續執行了。

儲存暫存器的值,一般用的是push指令,將對應的某些暫存器的值,乙個個放到棧中,把對應的值壓入到棧裡面,即所謂的壓棧。然後待被呼叫的子函式執行完畢的時候,再呼叫pop,把棧中的乙個個的值,賦值給對應的那些你剛開始壓棧時用到的暫存器,把對應的值從棧中彈出去,即所謂的出棧。其中儲存的暫存器中,也包括lr的值(因為用bl指令進行跳轉的話,那麼之前的pc 的值是存在lr中的),然後在子程式執行完畢的時候,再把棧中的lr的值pop出來,賦值給pc,這樣就實現了子函式的正確的返回。

2)  傳遞引數

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

3)臨時變數儲存在棧中

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

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

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

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

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

C語言及C 中static的總結

文章 c語言和c 中的static總結 c語言中的static static修飾區域性變數,使其生命週期變長,只在該作用域中使用,離開該作用域。該變數沒有被銷毀,還在記憶體中,即使再一次訪問,還是上一次變數的值,直到程式執行結束才釋放,被static修飾的區域性變數放在靜態區儲存區 static i...