堆棧、BSS段、代碼段、數據段、RO、RW、ZI等概念區分

堆棧、BSS段、代碼段、數據段、RO、RW、ZI等概念區分

一 預備知識

在區分一個程序的堆棧、bss、text段、RO、RW、ZI等概念時,首先區分一下程序進程和程序文件,然後瞭解一下哈弗結構和馮諾依曼結構。

程序進程就是程序運行時的程序,程序文件是編譯後生成的可執行文件,比如.bin文件等,這兩個概念很好區分,特別強調一下,分開表達主要是怕讀者在閱讀過程中混淆了。

哈佛結構和馮諾依曼結構的主要區別就是處理器能不能實現取指令和取數據的併發進行。嵌入式芯片中主要是哈佛結構,PC機上是馮諾依曼結構。

經典的哈佛結構:
程序存儲器和數據存儲器是各自獨立的存儲器。處理器應該有兩套總線,一套是程序存儲器的數據和地址總線,一套是數據存儲器的數據和地址總線。取指令和取數據能併發進行。51的程序進程的邏輯代碼段放在ROM中,而變量部分則放在RAM中,取ROM中的指令和RAM中的變量是兩套總線。

改進型哈佛結構:
程序存儲器和數據存儲器是各自獨立的存儲器。處理器只有一套總線,分時訪問程序存儲器和數據存儲器,但是在處理器中有icache和dcache將程序和數據分開,所以處理器仍然可以並步執行取指令和取數據。從ARM9開始以後所有的ARM處理器內核都是改進型的哈佛結構。ARM的邏輯代碼和變量都是存放在RAM中的,但是,它在內存中劃分了兩部分的空間,其中一部分放邏輯代碼,另一部分存放變量,之間不會相互干擾。

馮諾依曼結構:
沒有程序存儲空間和數據存儲空間之分。處理器只有一套總線,取指令和取數據是不能同時進行的。程序進程全部在RAM中,他們之間一般是按照代碼的執行順序依次存儲。由於全部在RAM中,運行速度快,所需的RAM多。

二 程序文件中的分區

備註:只針對嵌入式,pc程序文件沒有探究過。小標題“程序文件中的分區”其實不是很恰當,不知道該如何形容,此部分概念通常出現在一個程序編譯完成後的大小統計,請自行理解。

相關概念:Code,RO_data,RW_data,ZI_data,RO,RW,常出現在嵌入式程序編譯完成後的統計,例如MDK,IAR,ARM GCC。

有些技術文章中會直接使用RO,請注意區分RO和RO-data的區別。

Code: 即代碼域,它指的是編譯器生成的機器指令。

RO_data: ReadOnly data,即只讀數據域,它指程序中用到的只讀數據,全局變量,例如C語言中const關鍵字定義的全局變量就是典型的RO-data。

RW_data: ReadWrite data,即可讀寫數據域,它指初始化爲“非0值”的可讀寫數據,程序剛運行時,這些數據具有非0的初始值,且運行的時候它們會常駐在RAM區,因而應用程序可以修改其內容。例如全局變量或者靜態變量,且定義時賦予“非0值”給該變量進行初始化。

ZI_data: ZeroInitialie data,即0初始化數據,它指初始化爲“0值”的可讀寫數據域,它與RW_data的區別是程序剛運行時這些數據初始值全都爲0,而後續運行過程與RW-data的性質一樣,它們也常駐在RAM區,因而應用程序可以更改其內容。包括未初始化的全局變量,和初始化爲0的全局變量。

RO: 只讀區域,包括RO_data和code。

當程序存儲在ROM中時,所佔用的大小爲Code + RO_data + RW_data 。
當程序執行時, RW_data和 ZI_data在RAM中,RO_data和code視cpu架構(51、arm、x86)不同處於ROM或者RAM中。其中ZI_data對應了BSS段,RW_data對應數據段,code對應代碼段, RO_data對應數據段。

三 程序進程中的分區

相關概念:堆(heap),棧(stack),BSS段,數據段(data),代碼段(code /text),全局靜態區,文字常量區,程序代碼區。
BSS段: BSS段(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內存區域。
數據段: 數據段(data segment)通常是指用來存放程序中已初始化的全局變量的一塊內存區域。
代碼段: 代碼段(code segment/text segment)通常是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序運行前就已經確定,並且內存區域通常屬於只讀, 某些架構也允許代碼段爲可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
堆(heap):堆是用於存放進程運行中被動態分配的內存段,它的大小並不固定,可動態擴張或縮減。當進程調用malloc等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)。
棧(stack):棧又稱堆棧,用戶存放程序臨時創建的局部變量。在函數被調用時,其參數也會被壓入發起調用的進程棧中,並且待到調用結束後,函數的返回值也會被存放回棧中。由於棧的後進先出特點,所以棧特別方便用來保存/恢復調用現場。

全局靜態區,文字常量區,程序代碼區是從內存地址分配的角度來描述的。
全局區(靜態區)(static)—,全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。
文字常量區——常量字符串就是放在這裏的。
程序代碼區——存放函數體的二進制代碼。

針對上述概念,文章 https://www.cnblogs.com/huhuuu/p/3440187.html中具體描述了,例如對於初始化的全局變量和爲初始化的全局變量,雖然分別屬於數據段和BSS段,但在程序具體運行時,分配的內存地址是挨着的。同理,文字常量的地址也是連續的。

四 總結

以上幾個概念的對應關係如下表中所示:
備註:粉色部分的code和RO_data文字顏色爲灰色,表示可能發生在ROM,也可能發生在RAM,根據架構不同而不同。

在這裏插入圖片描述

參考
[1] ARM編譯中的RO、RW和ZI DATA區段 原文鏈接:https://blog.csdn.net/andylauren/article/details/52259652
[2] 從內存的角度觀察 堆、棧、全局區(靜態區)(static)、文字常量區、程序代碼區 原文鏈接:https://www.cnblogs.com/huhuuu/p/3440187.html
[3] 哈佛結構/馮諾依曼結構詳細分析 原文鏈接:https://blog.csdn.net/qq_25827755/article/details/52297383
[4] 對ARM9哈佛結構的認識 原文鏈接:http://www.cnblogs.com/amanlikethis/p/3344558.html

在這裏插入圖片描述

△微信掃一掃關注「邁微電子研發社」公衆號

知識星球:社羣旨在分享AI算法崗的秋招/春招準備攻略(含刷題)、面經和內推機會、學習路線、知識題庫等。
在這裏插入圖片描述

△掃碼加入「邁微電子研發社」學習輔導羣

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章