再次理解STM32中的堆栈机制
再次理解STM32中的堆棧機制
? ? ? ?剛拿到STM32時,你只編寫一個死循環(huán)
void main() { while(1); }BUILD://Program Size: Code=340 RO-data=252 RW-data=0 ZI-data=1632- 1
- 2
- 3
- 4
- 5
- 6
? ? ? ?編譯后,就會發(fā)現(xiàn)這么個程序已用了1600多的RAM,這要是在51單片機上,會心疼死了,這1600多的RAM跑哪兒去了,分析.map文件,你會發(fā)現(xiàn)是堆和棧占用的?
在startup_stm32f10x_md.s文件中,它的前面幾行就有以下定義:
- 1
- 2
? ? ? ?這下明白了吧,STM32在啟動的時候,RAM首先分配給使用到的全局變量,還有調(diào)用庫占用的一些數(shù)據(jù)(不太清楚是什么數(shù)據(jù))?
,然后再將剩余的空間分配給Heap和Stack。由于內(nèi)存空間是啟動時實現(xiàn)分配好的,所以當動態(tài)分配內(nèi)存的需求過多的時候,就會產(chǎn)生堆棧空間不足的問題。
查閱網(wǎng)上的資料,理解堆和棧的區(qū)別:?
- (1)棧區(qū)(stack):由編譯器自動分配和釋放,存放函數(shù)的參數(shù)值、局部變量的值等,其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。?
- (2)堆區(qū)(heap):一般由程序員分配和釋放,若程序員不釋放,程序結(jié)束時可能由操作系統(tǒng)回收。分配方式類似于數(shù)據(jù)結(jié)構(gòu)中的鏈表。?
- (3)全局區(qū)(靜態(tài)區(qū))(static):全局變量和靜態(tài)變量的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后由系統(tǒng)自動釋放。?
- (4)文字常量區(qū):常量字符串就是存放在這里的。?
- (5)程序代碼區(qū):存放函數(shù)體的二進制代碼。
例如:
int a=0; //全局初始化區(qū) char *p1; //全局未初始化區(qū) void main() {int b; //棧char s[]="abc"; //棧char *p3= "1234567"; //在文字常量區(qū)static int c =0 ; //靜態(tài)初始化區(qū)p1= (char *)malloc(10); //堆區(qū)strcpy(p1,"123456"); //"123456"放在常量區(qū) }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
? ? ? ?所以堆和棧的區(qū)別:?
- stack的空間由操作系統(tǒng)自動分配/釋放,heap上的空間手動分配/釋放。?
- stack的空間有限,heap是很大的自由存儲區(qū)。?
- 程序在編譯期和函數(shù)分配內(nèi)存都是在棧上進行,且程序運行中函數(shù)調(diào)用時參數(shù)的傳遞也是在棧上進行。
? ? ? ?顯然 Cortex-m3資料可知:__initial_sp是堆棧指針,它就是FLASH的0x8000000地址前面4個字節(jié)(它根據(jù)堆棧大小,由編譯器自動生成)?
顯然堆和棧是相鄰的。
堆和棧空間分配:?
- 棧:向低地址擴展?
- 堆:向高地址擴展
? ? ? ?顯然如果依次定義變量,先定義的棧變量的內(nèi)存地址比后定義的棧變量的內(nèi)存地址要大,先定義的堆變量的內(nèi)存地址比后定義的堆變量的內(nèi)存地址要小。
堆和棧變量:?
- 棧:臨時變量,退出該作用域就會自動釋放?
- 堆:malloc變量,通過free函數(shù)釋放
寫程序時應(yīng)該注意:?
1. 所以最好是不要調(diào)用太深。?
2. 局部變量不要太大太多,如局部數(shù)組,超過某個數(shù)量需定義為全局數(shù)組,因為局部數(shù)組同樣儲存在堆棧中。
總結(jié)
以上是生活随笔為你收集整理的再次理解STM32中的堆栈机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IAR环境下STM32+IAP方案的实现
- 下一篇: STM32中断优先级和开关总中断(很老很