看關(guān)于單片機(jī)方面的書(shū)籍的時(shí)候,總是能看到別人說(shuō)的一些堆棧啊什么的操作,之前看到這個(gè)術(shù)語(yǔ)就直接跳過(guò),沒(méi)想到去探究單片機(jī)內(nèi)部的原理。但是最近課程學(xué)習(xí)微機(jī)原理這門(mén)課,需要我們寫(xiě)匯編程序,匯編里面經(jīng)常遇到堆棧這個(gè)東西,所以就找了個(gè)時(shí)間把堆棧給徹底的搞一下。
如果了解一點(diǎn)匯編編程話,就可以知道,堆棧是內(nèi)存中一段連續(xù)的存儲(chǔ)區(qū)域,用來(lái)保存一些臨時(shí)數(shù)據(jù)。通常用來(lái)保存CALL指令調(diào)用子程序時(shí)的返回地址,RET指令從堆棧中獲取返回地址。中斷指令I(lǐng)NT調(diào)用中斷程序時(shí),將標(biāo)志寄存器值、代碼段寄存器CS值、指令指針寄存器IP值保存在堆棧中。
堆棧也可以用來(lái)保存其他數(shù)據(jù)。
堆棧操作由PUSH,POP兩條指令來(lái)完成;
堆棧操作的操作數(shù)均為子類(lèi)型(兩個(gè)字節(jié))進(jìn)行操作。
程序內(nèi)存可以分為幾個(gè)區(qū),棧區(qū)(stack),堆區(qū)(Heap),全局區(qū)(static),文字常亮區(qū),程序代碼區(qū)。
程序編譯之后,全局變量,靜態(tài)變量已經(jīng)分配好內(nèi)存空間,在函數(shù)運(yùn)行時(shí),程序需要為局部變量分配??臻g,當(dāng)中斷來(lái)時(shí),也需要將函數(shù)指針入棧,保護(hù)現(xiàn)場(chǎng),以便于中斷處理完之后再回到之前執(zhí)行的函數(shù)。
棧是從高到低分配,堆是從低到高分配。
我們一般說(shuō)的堆棧指的棧。堆棧又分硬堆棧和軟堆棧,硬堆棧即SP,從片內(nèi)RAM的頂部向下生長(zhǎng)。軟堆棧在硬堆棧跟全局變量區(qū)之間的空間,C51函數(shù)調(diào)用通過(guò)R0-R7和棧來(lái)實(shí)現(xiàn)。
為什么單片機(jī)啟動(dòng)時(shí),不需要用bootloader將代碼從ROM搬移到RAM,而ARM則需要。這里我們可以先看看單片機(jī)程序執(zhí)行的過(guò)程,單片機(jī)執(zhí)行分三個(gè)步驟,取執(zhí)行---分析指令----執(zhí)行指令。取指令的任務(wù)是:根據(jù)PC的值從程序存儲(chǔ)器讀出指令,送到指令寄存器。然后分析執(zhí)行執(zhí)行。這樣單片機(jī)就從內(nèi)部程序存儲(chǔ)器去代碼指令,從RAM存取相關(guān)數(shù)據(jù)。要知道RAM取數(shù)的速度是遠(yuǎn)高于ROM的,但是單片機(jī)因?yàn)楸旧磉\(yùn)行頻率不高,所以從ROM取指令慢并不影響。而ARM不同,cpu運(yùn)行的頻率高,遠(yuǎn)大于從ROM讀寫(xiě)的速度,所以一般有操作系統(tǒng),都需要將代碼部分拷貝到RAM中再執(zhí)行。

再來(lái)看一個(gè)網(wǎng)上很流行的經(jīng)典例子:
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); 堆
}
不知道你是否有點(diǎn)明白了,堆和棧的第一個(gè)區(qū)別就是申請(qǐng)方式不同:棧(英文名稱(chēng)是stack)是系統(tǒng)自動(dòng)分配空間的,例如我們定義一個(gè) char a;系統(tǒng)會(huì)自動(dòng)在棧上為其開(kāi)辟空間。而堆(英文名稱(chēng)是heap)則是程序員根據(jù)需要自己申請(qǐng)的空間,例如malloc(10);開(kāi)辟十個(gè)字節(jié)的空間。由于棧上的空間是自動(dòng)分配自動(dòng)回收的,所以棧上的數(shù)據(jù)的生存周期只是在函數(shù)的運(yùn)行過(guò)程中,運(yùn)行后就釋放掉,不可以再訪問(wèn)。而堆上的數(shù)據(jù)只要程序員不釋放空間,就一直可以訪問(wèn)到,不過(guò)缺點(diǎn)是一旦忘記釋放會(huì)造成內(nèi)存泄露。
網(wǎng)上一個(gè)很好的比喻,摘抄下來(lái),以便理解:
使用棧就象我們?nèi)ワ堭^里吃飯,只管點(diǎn)菜(發(fā)出申請(qǐng))、付錢(qián)、和吃(使用),吃飽了就走,不必理會(huì)切菜、洗菜等準(zhǔn)備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。
使用堆就象是自己動(dòng)手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。
總結(jié):
其實(shí)堆棧就是單片機(jī)中的一些存儲(chǔ)單元,這些存儲(chǔ)單元被指定保存一些特殊信息,比如地址(保護(hù)斷點(diǎn))和數(shù)據(jù)(保護(hù)現(xiàn)場(chǎng))。
如果非要給他加幾個(gè)特點(diǎn)的話那就是:1、這些存儲(chǔ)單元中的內(nèi)容都是程序執(zhí)行過(guò)程中被中斷打斷時(shí),事故現(xiàn)場(chǎng)的一些相關(guān)參數(shù)。如果不保存這些參數(shù),單片機(jī)執(zhí)行完中斷函數(shù)后就無(wú)法回到主程序繼續(xù)執(zhí)行了。
2、這些存儲(chǔ)單元的地址被記在了一個(gè)叫做堆棧指針(SP)的地方。
好了,以上就是這些。
編輯:hfy
-
單片機(jī)
+關(guān)注
關(guān)注
6078文章
45565瀏覽量
673235 -
寄存器
+關(guān)注
關(guān)注
31文章
5617瀏覽量
130378 -
RAM
+關(guān)注
關(guān)注
8文章
1400瀏覽量
120964 -
Call
+關(guān)注
關(guān)注
0文章
9瀏覽量
8522 -
堆棧
+關(guān)注
關(guān)注
0文章
183瀏覽量
20571
發(fā)布評(píng)論請(qǐng)先 登錄
關(guān)于單片機(jī)堆棧操作:堆棧是單片機(jī)中的存儲(chǔ)單元
評(píng)論