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