剛拿到STM32時(shí),你只編寫一個(gè)死循環(huán)
編譯后,就會(huì)發(fā)現(xiàn)這么個(gè)程序已用了1600多的RAM,這要是在51單片機(jī)上,會(huì)心疼死了,這1600多的RAM跑哪兒去了,分析.map文件,你會(huì)發(fā)現(xiàn)是堆和棧占用的
在startup_stm32f10x_md.s文件中,它的前面幾行就有以下定義:
這下明白了吧,STM32在啟動(dòng)的時(shí)候,RAM首先分配給使用到的全局變量,還有調(diào)用庫占用的一些數(shù)據(jù)(不太清楚是什么數(shù)據(jù)),然后再將剩余的空間分配給Heap和Stack。由于內(nèi)存空間是啟動(dòng)時(shí)實(shí)現(xiàn)分配好的,所以當(dāng)動(dòng)態(tài)分配內(nèi)存的需求過多的時(shí)候,就會(huì)產(chǎn)生堆棧空間不足的問題。
查閱網(wǎng)上的資料,理解堆和棧的區(qū)別:
- (1)棧區(qū)(stack):由編譯器自動(dòng)分配和釋放,存放函數(shù)的參數(shù)值、局部變量的值等,其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
- (2)堆區(qū)(heap):一般由程序員分配和釋放,若程序員不釋放,程序結(jié)束時(shí)可能由操作系統(tǒng)回收。分配方式類似于數(shù)據(jù)結(jié)構(gòu)中的鏈表。
- (3)全局區(qū)(靜態(tài)區(qū))(static):全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后由系統(tǒng)自動(dòng)釋放。
- (4)文字常量區(qū):常量字符串就是存放在這里的。
- (5)程序代碼區(qū):存放函數(shù)體的二進(jìn)制代碼。
例如:
所以堆和棧的區(qū)別:
- stack的空間由操作系統(tǒng)自動(dòng)分配/釋放,heap上的空間手動(dòng)分配/釋放。
- stack的空間有限,heap是很大的自由存儲(chǔ)區(qū)。
- 程序在編譯期和函數(shù)分配內(nèi)存都是在棧上進(jìn)行,且程序運(yùn)行中函數(shù)調(diào)用時(shí)參數(shù)的傳遞也是在棧上進(jìn)行。
顯然 Cortex-m3資料可知:__initial_sp是堆棧指針,它就是FLASH的0x8000000地址前面4個(gè)字節(jié)(它根據(jù)堆棧大小,由編譯器自動(dòng)生成)顯然堆和棧是相鄰的。
堆和??臻g分配:
- 棧:向低地址擴(kuò)展- 堆:向高地址擴(kuò)展
顯然如果依次定義變量,先定義的棧變量的內(nèi)存地址比后定義的棧變量的內(nèi)存地址要大,先定義的堆變量的內(nèi)存地址比后定義的堆變量的內(nèi)存地址要小。
堆和棧變量:
- 棧:臨時(shí)變量,退出該作用域就會(huì)自動(dòng)釋放- 堆:malloc變量,通過free函數(shù)釋放
寫程序時(shí)應(yīng)該注意:
1. 所以最好是不要調(diào)用太深。2. 局部變量不要太大太多,如局部數(shù)組,超過某個(gè)數(shù)量需定義為全局?jǐn)?shù)組,因?yàn)榫植繑?shù)組同樣儲(chǔ)存在堆棧中。
-
STM32
+關(guān)注
關(guān)注
2264文章
10854瀏覽量
354307 -
堆棧
+關(guān)注
關(guān)注
0文章
182瀏覽量
19717
原文標(biāo)題:再次理解STM32中的堆棧機(jī)制,通俗易懂~
文章出處:【微信號(hào):Mouser-Community,微信公眾號(hào):貿(mào)澤電子設(shè)計(jì)圈】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論