堆栈、BSS段、代码段、数据段/RO、RW、ZI
嵌入式_堆棧、BSS段、代碼段、數(shù)據(jù)段/RO、RW、ZI
提示:這里只針對(duì)ARM嵌入式系統(tǒng)所說(shuō),PC端和其他系統(tǒng)不議
文章目錄
- 嵌入式_堆棧、BSS段、代碼段、數(shù)據(jù)段/RO、RW、ZI
- 前言
- 一、代碼態(tài)
- 二、存儲(chǔ)態(tài)
- 三、運(yùn)行態(tài)
- 四、運(yùn)行過(guò)程
- 總結(jié)
前言
剛好做單片機(jī)的相關(guān)項(xiàng)目,學(xué)習(xí)到基礎(chǔ)內(nèi)容,主要寫(xiě)個(gè)博客幫助自己總結(jié)和梳理知識(shí),根據(jù)自己的理解和邏輯重新梳理順序的,歡迎指正。
一、代碼態(tài)
代碼態(tài)就是使用keil-MDK編譯出來(lái)的準(zhǔn)備燒錄的二進(jìn)制文件,現(xiàn)在只是文件,既沒(méi)有燒錄更沒(méi)有運(yùn)行。
例如使用keil編譯的工程,打開(kāi).map文件最底下顯示如圖:
Code(代碼部分):一般是程序執(zhí)行代碼部分,編譯器生成的機(jī)器指令(指令又包含操作碼和操作數(shù),此處不細(xì)說(shuō))。
RO_data(read only): 程序中用到的除了內(nèi)聯(lián)數(shù)據(jù)的只讀數(shù)據(jù),全局變量,典型為const修飾的全局變量,(注:要區(qū)別于下述的:RO)
RW_data(ReadWrite):可讀寫(xiě)數(shù)據(jù)部分,初始化不為0的全局變量和static修飾的靜態(tài)變量(包含全局變量和局部變量),這些數(shù)據(jù)運(yùn)行時(shí)候長(zhǎng)駐RAM區(qū)執(zhí)行讀寫(xiě)操作。
ZI_data(zero):未初始化或初始化為0的全局變量和靜態(tài)變量(包含全局變量和局部變量),與RW_data的區(qū)別是初始化賦的值,運(yùn)行是和RW_data一樣。
實(shí)驗(yàn):可以使用keil手動(dòng)編寫(xiě)一個(gè)C語(yǔ)言程序,初始化和不初始化或初始化為0的全局變量,靜態(tài)變量和只讀變量然后查看map文件信息。該實(shí)驗(yàn)參見(jiàn)我的另一篇博客:https://blog.csdn.net/Yin_w/article/details/129541728
二、存儲(chǔ)態(tài)
存儲(chǔ)狀態(tài)就是燒錄到機(jī)器而沒(méi)有運(yùn)行的二進(jìn)制文件,可以是Flash或ROM。
RO:Total RO Size (Code + RO Data),只讀數(shù)據(jù),存儲(chǔ)在ROM或Flash中,運(yùn)行時(shí)被加載到RAM區(qū)
RW:Total RW Size (RW Data + ZI Data),讀寫(xiě)數(shù)據(jù)
ROM:Total ROM Size (Code + RO Data + RW Data),燒錄/下載程序到Falsh或者ROM時(shí),所占的最小空間
剩下的ZI_data不被包含到ROM中,是因?yàn)槌跏蓟凳橇?#xff0c;只需要在RAM中執(zhí)行時(shí)將ZI_data所在區(qū)域擦除即可
三、運(yùn)行態(tài)
程序運(yùn)行時(shí)候涉及的概念比較多,如圖是在RAM中運(yùn)行時(shí)的數(shù)據(jù)與存儲(chǔ)位置的狀態(tài)(根據(jù)框架不同,有些數(shù)據(jù)也在ROM中運(yùn)行,此處不細(xì)說(shuō)),運(yùn)行時(shí)將ROM中的代碼數(shù)據(jù)和只讀數(shù)據(jù)分別加載到RAM的text代碼段和data段中。
保留區(qū):一般是出廠(chǎng)信息或者編碼信息
text代碼段:指令將RO中的程序代碼加載到此處,
靜態(tài)存儲(chǔ)區(qū):靜態(tài)存儲(chǔ)區(qū)分為.bss段和.data段;RO中的RO_data只讀數(shù)據(jù)和RW中的RW_data數(shù)據(jù)會(huì)被加載到此處的.data段,而游離的ZI_data數(shù)據(jù)此時(shí)被加載到.bss區(qū)。
Heap堆區(qū):用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,其大小不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc堆區(qū)域被擴(kuò)張,調(diào)用free堆區(qū)被縮減。
Stack棧區(qū):用戶(hù)存放程序臨時(shí)創(chuàng)建的局部變量。函數(shù)被調(diào)用時(shí),其參數(shù)也會(huì)被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會(huì)被存放回棧中。由于棧的后進(jìn)先出特點(diǎn),所以棧特別方便用來(lái)保存/恢復(fù)調(diào)用現(xiàn)場(chǎng)
內(nèi)核區(qū):內(nèi)核運(yùn)行的區(qū)域,此處不細(xì)說(shuō)
注意:我們一般說(shuō)的堆棧是指的棧區(qū):堆是堆,棧是棧,堆棧是棧
二者的區(qū)別總結(jié)為:
A.分配方式不同:棧由操作系統(tǒng)自動(dòng)分配釋放;堆的申請(qǐng)和釋放工作由程序員手動(dòng)控制;
B.生長(zhǎng)方向不同:堆內(nèi)存地址由低到高(向上);棧的內(nèi)存地址由高到低(向下);
C.存放內(nèi)容不同:棧動(dòng)態(tài)存放函數(shù)返回地址、參數(shù)、局部變量和寄存器值等。堆頂一字節(jié)存放堆的大小,堆中具體內(nèi)容由程序員填充。
D.存在狀態(tài)不同:程序運(yùn)行時(shí)候,棧區(qū)隨程序運(yùn)行狀態(tài)而動(dòng)態(tài)變化,堆區(qū)則是靜態(tài)的,申請(qǐng)則有,改寫(xiě)則變,釋放則無(wú)
四、運(yùn)行過(guò)程
由運(yùn)行態(tài)和存儲(chǔ)態(tài)可以知道,燒錄到ROM中的二進(jìn)制文件和運(yùn)行的程序并不一致,這就需要知道程序運(yùn)行過(guò)程是怎樣的。
1.首先從存儲(chǔ)態(tài)將RW從ROM中搬到RAM中,因?yàn)镽W是變量,變量不能存在ROM中。
2.將ZI所在的RAM區(qū)域全部清零,因?yàn)閆I區(qū)域并不在Image中,所以需要程序根據(jù)編譯器給出的ZI地址及大小來(lái)將相應(yīng)得RAM區(qū)域清零。ZI中也是變量,同理:變量不能存在ROM中
在程序運(yùn)行的最初階段,RO中的指令完成了這兩項(xiàng)工作后C程序才能正常訪(fǎng)問(wèn)變量。否則只能運(yùn)行不含變量的代碼。
根據(jù)以上概念、各個(gè)階段程序數(shù)據(jù)和存儲(chǔ)位置的映射關(guān)系,合成理解圖如圖所示:
淺黃色部分的code和RO_data文字顏色為灰色,表示可能發(fā)生在ROM,也可能發(fā)生在RAM,根據(jù)架構(gòu)不同而不同
總結(jié)
如有錯(cuò)誤,歡迎指正,原創(chuàng)不易,轉(zhuǎn)載留名!
總結(jié)
以上是生活随笔為你收集整理的堆栈、BSS段、代码段、数据段/RO、RW、ZI的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 中国税务申报软件市场深度研究分析报告
- 下一篇: 从单片机初学者迈向单片机工程师前传---