看關于單片機方面的書籍的時候,總是能看到別人說的一些堆棧啊什么的操作,之前看到這個術語就直接跳過,沒想到去探究單片機內部的原理。但是最近課程學習微機原理這門課,需要我們寫匯編程序,匯編里面經常遇到堆棧這個東西,所以就找了個時間把堆棧給徹底的搞一下。
如果了解一點匯編編程話,就可以知道,堆棧是內存中一段連續(xù)的存儲區(qū)域,用來保存一些臨時數據。通常用來保存CALL指令調用子程序時的返回地址,RET指令從堆棧中獲取返回地址。中斷指令INT調用中斷程序時,將標志寄存器值、代碼段寄存器CS值、指令指針寄存器IP值保存在堆棧中。
堆棧也可以用來保存其他數據。
堆棧操作由PUSH,POP兩條指令來完成;
堆棧操作的操作數均為子類型(兩個字節(jié))進行操作。
程序內存可以分為幾個區(qū),棧區(qū)(stack),堆區(qū)(Heap),全局區(qū)(static),文字常亮區(qū),程序代碼區(qū)。
程序編譯之后,全局變量,靜態(tài)變量已經分配好內存空間,在函數運行時,程序需要為局部變量分配??臻g,當中斷來時,也需要將函數指針入棧,保護現場,以便于中斷處理完之后再回到之前執(zhí)行的函數。
棧是從高到低分配,堆是從低到高分配。
我們一般說的堆棧指的棧。堆棧又分硬堆棧和軟堆棧,硬堆棧即SP,從片內RAM的頂部向下生長。軟堆棧在硬堆棧跟全局變量區(qū)之間的空間,C51函數調用通過R0-R7和棧來實現。
為什么單片機啟動時,不需要用bootloader將代碼從ROM搬移到RAM,而ARM則需要。這里我們可以先看看單片機程序執(zhí)行的過程,單片機執(zhí)行分三個步驟,取執(zhí)行---分析指令----執(zhí)行指令。取指令的任務是:根據PC的值從程序存儲器讀出指令,送到指令寄存器。然后分析執(zhí)行執(zhí)行。這樣單片機就從內部程序存儲器去代碼指令,從RAM存取相關數據。要知道RAM取數的速度是遠高于ROM的,但是單片機因為本身運行頻率不高,所以從ROM取指令慢并不影響。而ARM不同,cpu運行的頻率高,遠大于從ROM讀寫的速度,所以一般有操作系統(tǒng),都需要將代碼部分拷貝到RAM中再執(zhí)行。
再來看一個網上很流行的經典例子:
main.cpp
int a = 0; 全局初始化區(qū)
char *p1; 全局未初始化區(qū)
main()
{
int b; 棧
char s[] = “abc”; 棧
char *p2; 棧
char *p3 = “123456”; 123456/0在常量區(qū),p3在棧上。
static int c =0; 全局(靜態(tài))初始化區(qū)
p1 = (char *)malloc(10); 堆
p2 = (char *)malloc(20); 堆
}
不知道你是否有點明白了,堆和棧的第一個區(qū)別就是申請方式不同:棧(英文名稱是stack)是系統(tǒng)自動分配空間的,例如我們定義一個 char a;系統(tǒng)會自動在棧上為其開辟空間。而堆(英文名稱是heap)則是程序員根據需要自己申請的空間,例如malloc(10);開辟十個字節(jié)的空間。由于棧上的空間是自動分配自動回收的,所以棧上的數據的生存周期只是在函數的運行過程中,運行后就釋放掉,不可以再訪問。而堆上的數據只要程序員不釋放空間,就一直可以訪問到,不過缺點是一旦忘記釋放會造成內存泄露。
網上一個很好的比喻,摘抄下來,以便理解:
使用棧就象我們去飯館里吃飯,只管點菜(發(fā)出申請)、付錢、和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。
總結:
其實堆棧就是單片機中的一些存儲單元,這些存儲單元被指定保存一些特殊信息,比如地址(保護斷點)和數據(保護現場)。
如果非要給他加幾個特點的話那就是:1、這些存儲單元中的內容都是程序執(zhí)行過程中被中斷打斷時,事故現場的一些相關參數。如果不保存這些參數,單片機執(zhí)行完中斷函數后就無法回到主程序繼續(xù)執(zhí)行了。
2、這些存儲單元的地址被記在了一個叫做堆棧指針(SP)的地方。
好了,以上就是這些。
編輯:hfy
-
單片機
+關注
關注
6041文章
44616瀏覽量
637419 -
寄存器
+關注
關注
31文章
5363瀏覽量
120914 -
RAM
+關注
關注
8文章
1369瀏覽量
114870 -
Call
+關注
關注
0文章
9瀏覽量
8336 -
堆棧
+關注
關注
0文章
182瀏覽量
19800
發(fā)布評論請先 登錄
相關推薦
評論