1. 程式人生 > >KEIL編譯器區分RW-data和ZI-data

KEIL編譯器區分RW-data和ZI-data

原文地址::https://blog.csdn.net/xiaogu0322/article/details/78218638?locationNum=10&fps=1

相關文章

1、keil5編譯後生成 Program Size: Code RO-data RW-data ZI-data是什麼----https://blog.csdn.net/ylzmm/article/details/79233560

2、詳解STM32編譯後Code-RO-data-RW-data-ZI-data----https://blog.csdn.net/kaspar1992/article/details/52805474?utm_source=itdadao&utm_medium=referral

 

 

 

KEIL工程的編譯提示輸出資訊中有一個語句“Program Size:Code=xx RO-data=xx RW-data=xx ZI-data=xx”,它說明了程式各個域的大小,編譯後,應用程式中所有具有同一性質的資料(包括程式碼)被歸到一個域,程式在儲存或執行的時候,不同的域會呈現不同的狀態,這些域的意義如下:

  1. Code:即程式碼域,它指的是編譯器生成的機器指令,這些內容被儲存到ROM區。

  2. RO-data:Read Only data,即只讀資料域,它指程式中用到的只讀資料,這些資料被儲存在ROM區,因而程式不能修改其內容。例如C語言中const關鍵字定義的變數就是典型的RO-data。

  3. RW-data:Read Write data,即可讀寫資料域,它指初始化為“非0值”的可讀寫資料,程式剛執行時,這些資料具有非0的初始值,且執行的時候它們會常駐在RAM區,因而應用程式可以修改其內容。例如C語言中使用定義的全域性變數,且定義時賦予“非0值”給該變數進行初始化。

  4. ZI-data:Zero Initialie data,即0初始化資料,它指初始化為“0值”的可讀寫資料域,它與RW-data的區別是程式剛執行時這些資料初始值全都為0,而後續執行過程與RW-data的性質一樣,它們也常駐在RAM區,因而應用程式可以更改其內容。例如C語言中使用定義的全域性變數,且定義時賦予“0值”給該變數進行初始化(若定義該變數時沒有賦予初始值,編譯器會把它當ZI-data來對待,初始化為0);

  5. ZI-data的棧空間(Stack)及堆空間(Heap):在C語言中,函式內部定義的區域性變數屬於棧空間,進入函式的時候從向棧空間申請記憶體給區域性變數,退出時釋放區域性變數,歸還記憶體空間。而使用malloc動態分配的變數屬於堆空間。在程式中的棧空間和堆空間都是屬於ZI-data區域的,這些空間都會被初始值化為0值。編譯器給出的ZI-data佔用的空間值中包含了堆疊的大小(經實際測試,若程式中完全沒有使用malloc動態申請堆空間,編譯器會優化,不把堆空間計算在內)。

RW-data和ZI-data它們僅僅是初始值不一樣而已,為什麼編譯器非要把它們區分開?這就涉及到程式的儲存狀態了,應用程式具有靜止狀態和執行狀態。靜止態的程式被儲存在非易失儲存器中,如STM32的內部FLASH,因而系統掉電後也能正常儲存。但是當程式在執行狀態的時候,程式常常需要修改一些暫存資料,由於執行速度的要求,這些資料往往存放在記憶體中(RAM),掉電後這些資料會丟失。因此,程式在靜止與執行的時候它在儲存器中的表現是不一樣的。 
這裡寫圖片描述
圖中的左側是應用程式的儲存狀態,右側是執行狀態,而上方是RAM儲存器區域,下方是ROM儲存器區域。 
程式在儲存狀態時,RO節(RO section)及RW節都被儲存在ROM區。當程式開始執行時,核心直接從ROM中讀取程式碼,並且在執行主體程式碼前,會先執行一段載入程式碼,它把RW節資料從ROM複製到RAM, 並且在RAM加入ZI節,ZI節的資料都被初始化為0。載入完後RAM區準備完畢,正式開始執行主體程式。 
編譯生成的RW-data的資料屬於圖中的RW節,ZI-data的資料屬於圖中的ZI節。是否需要掉電儲存,這就是把RW-data與ZI-data區別開來的原因,因為在RAM建立資料的時候,預設值為0,但如果有的資料要求初值非0,那就需要使用ROM記錄該初始值,執行時再複製到RAM。 
STM32的RO區域不需要載入到SRAM,核心直接從FLASH讀取指令執行。計算機系統的應用程式執行過程很類似,不過計算機系統的程式在儲存狀態時位於硬碟,執行的時候甚至會把上述的RO區域(程式碼、只讀資料)載入到記憶體,加快執行速度,還有虛擬記憶體管理單元(MMU)輔助載入資料,使得可以執行比實體記憶體還大的應用程式。而STM32沒有MMU,所以無法支援Linux和Windows系統。 
當程式儲存到STM32晶片的內部FLASH時(即ROM區),它佔用的空間是Code、RO-data及RW-data的總和,所以如果這些內容比STM32晶片的FLASH空間大,程式就無法被正常儲存了。當程式在執行的時候,需要佔用內部SRAM空間(即RAM區),佔用的空間包括RW-data和ZI-data。應用程式在各個狀態時各區域的組成見表 。

ROM(FLASH) = Code + RO-data +RW-data;

RAM size = RW-data + ZI-data;

對於STM32F103xxyy系列: 
第一個x代表引腳數:T-36pin,C-48pin,R-64pin,V-100pin,Z-144pin; 
第二個x代表Flash容量:6-32K,8-64K,B-128K,C-256K,D-384K,E-512K; 
第一個y代表封裝:H-BGA封裝,T-LQFP封裝,U-QFN封裝; 
第二個一代表工作穩定範圍:6代表-40到85攝氏度,7代表-40到105攝氏度。