基礎篇 03 堆的初始化及 map 檔案

2021-08-28 06:39:50 字數 2195 閱讀 7136

堆疊,是我們常常會聽說過的詞彙。搞嵌入式如果說不懂得堆疊可能會被懷疑學習了乙個假的嵌入式。不過,坦白來說,我還是不太理解其中的細節,比如說棧的位置在哪?我們說棧是先進後出filo形式的資料結構,堆是先進fifo先出的形式的資料結構。棧是由系統操作的,而堆是由程式設計師操作的。我感覺這些解釋都是玄而又玄的說法,我現在還沒有理清頭緒,以後有具體頭緒了再來寫出我的想法。現在先學習大佬的想法:

cpu 用 push 指令來將資料壓棧,用 pop 指令來彈棧。當用 push 壓棧時,sp 值減少(向低位址擴充套件)。當用 pop 彈棧時,sp 值增大。儲存和獲取資料都是 cpu 暫存器的值。

當函式被呼叫時,cpu使用特定的指令把當前的 ip (譯者注:「instruction pointer」,是乙個暫存器,用來記錄 cpu 指令的位置)壓棧。即執行**的位址。cpu 接下來將呼叫函式位址賦給 ip ,進行呼叫。當函式返回時,舊的 ip 被彈棧,cpu 繼續去函式呼叫之前的**。

當進入函式時,sp 向下擴充套件,擴充套件到確保為函式的區域性變數留足夠大小的空間。如果函式中有乙個 32-bit 的區域性變數會在棧中留夠四位元組的空間。當函式返回時,sp 通過返回原來的位置來釋放空間。

如果函式有引數的話,在函式呼叫之前,會將引數壓棧。函式中的**通過 sp 的當前位置來定位引數並訪問它們。

函式巢狀呼叫和使用魔法一樣,每一次新呼叫的函式都會分配函式引數,返回值位址、區域性變數空間、巢狀呼叫的活動記錄都要被壓入棧中。函式返回時,按照正確方式的撤銷。

棧要受到記憶體塊的限制,不斷的函式巢狀/為區域性變數分配太多的空間,可能會導致棧溢位。當棧中的記憶體區域都已經被使用完之後繼續向下寫(低位址),會觸發乙個 cpu 異常。這個異常接下會通過語言的執行時轉成各種型別的棧溢位異常。(譯者注:「不同語言的異常提示不同,因此通過語言執行時來轉換」我想他表達的是這個含義) 

具體內容可以參看這個部落格

不過在本次的內容中,不對棧做研究,只討論堆的話題。例如:在rt-thread下堆是怎麼使用的?以及如何從xx.map中獲取有關資料?

/* 執行緒入口 */

void thread1_entry(void *parameter)

/* 每次分配 (1 << i) 大小位元組數的記憶體空間 */

ptr = rt_realloc(ptr,1 << i);

// ptr = rt_malloc(1 << i);

/* 如果分配成功 */

if (ptr != rt_null)

else

rt_thread_mdelay(1000);

rt_free(ptr);

}// ptr = rt_calloc(a,b);

// if(ptr != rt_null)

//

// else

//

}

記憶體的申請函式:

rt_malloc(xx);

rt_realloc(xx,xx);

rt_calloc(xx,xx);

記憶體的刪除函式:

rt_free(xx);

在學習過程中,有乙個初步接觸得東西xx.map檔案

雙擊這個,就可以得到rtthread-stm32.map的檔案。

ro rw rom的具體意義

program size: code=908 ro-data=320 rw-data=0 zi-data=1024code:指**的大小;

ro-data:指除了內聯資料(inline data)之外的常量資料;

rw-data:指可讀寫(rw)、已初始化的變數資料;

zi-data:指未初始化(zi)的變數資料;

code、ro-data:位於flash中;

rw-data、zi-data:位於ram中;

map檔案的具體意義,請參看:

golang中map宣告及初始化

map的宣告 var m1 map string int map key value key必須支援 避免使用浮點型 value不做規範 map的初始化 方式1 var m1 map string int map sting int 方式2 m2 make map string int 注意 map...

關於Map初始化的問題

在向前端傳遞日誌資訊時使用的時list map形式,即map中放每條日誌,list中放日誌列表,但在介面測試時發現傳遞的日誌都是一樣的 如下 然後開始慢慢排查 1.資料庫中的記錄是正常的 2.直接輸出loglist和迴圈中的log,result都是正常的 問題處在list這個格式,這裡list儲存的...

golang語言中map的初始化及使用

先宣告map var m1 map string string 再使用make函式建立乙個非nil的map,nil map不能賦值 m1 make map string string 最後給已宣告的map賦值 m1 a aa m1 b bb 直接建立 m2 make map string strin...