版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、Good is good, but better carries it.精益求精,善益求善。C程序的詳細執(zhí)行過程-嵌入式C語言程序的運行2011-08-1615:05我們做C語言中這么多年,都知道這樣一句話,C語言代碼形成可執(zhí)行程序,需要經過編譯-匯編-鏈接三個階段。背都背熟了,但是到底啥意思,每一步都會產生一些什么東西,很多人都不是太了解。今天就詳細的來說說這個問題:先看下圖,在這個圖中,我詳細的描述了,整個過程及中間的一些步驟:代碼段,只讀數(shù)據(jù)段,讀寫數(shù)據(jù)段,未初始化數(shù)據(jù)段屬于靜態(tài)區(qū)域。棧和堆屬于動態(tài)區(qū)域。代碼段,只讀數(shù)據(jù)段和讀寫數(shù)據(jù)段將在連接之后產生,未初始化數(shù)據(jù)段將在程序初始化的時候開
2、辟,而堆和棧將在程序的運行中分配和釋放。C語言程序分為映像和運行兩種狀態(tài)。在編譯連接后形成的映像中,將只包含代碼段,只讀數(shù)據(jù)段和讀寫數(shù)據(jù)段。在程序運行之前,將動態(tài)生成未初始化數(shù)據(jù)段,在程序的運行時還將動態(tài)形成堆和棧區(qū)域。在嵌入式系統(tǒng)中,程序最終是要放置在內存中運行的,程序的幾個段,最終會轉化為內存中的幾個區(qū)域。C語言可執(zhí)行程序的內存布局如圖13-5所示。圖13-5C語言可執(zhí)行程序的內存布局在內存中,從低地址到高地址,依次是只讀段、讀寫段、未初始化數(shù)據(jù)段、堆段、棧段。映像文件中將包含代碼段(Code)、只讀數(shù)據(jù)段(ROData)以及讀寫數(shù)據(jù)段(RWData),未初始化數(shù)據(jù)段(BSS)將在程序的初
3、始化階段中開辟,堆棧在程序運行時動態(tài)開辟。只讀區(qū)(RO)包括了代碼和只讀數(shù)據(jù),在內存區(qū)域中,代碼段(Code)和只讀數(shù)據(jù)段(RoData)的存放形式上基本沒有區(qū)別。對于程序運行時的內存使用,堆和棧一般是相向擴展的。堆的分配由程序決定,棧由編譯器管理。在以上概念中,只是一種內存分布,并沒有考慮實際系統(tǒng)的情況。在實際的系統(tǒng)中,程序有載入和運行兩個概念。嵌入式系統(tǒng)由兩種內存,一種是可以固化只讀的內存(如:ROM,NorFlash),另一種是易失的可讀寫的內存(如:SRAM和SDRAM)。程序中的各個段也有需要固化和需要讀寫的。程序中的各段必須載入到內存的恰當位置,程序才可以運行。C語言各部分的需要固
4、化和可寫的情況如表13-2所示。表13-2C語言各部分的需要支持固化和可寫的情況段需要固化需要可寫代碼(Code)是否只讀數(shù)據(jù)(ROdata)是否讀寫數(shù)據(jù)(RWdata)是是未初始化數(shù)據(jù)(BSS)否是堆(heap)否是棧(stack)否是在嵌入式系統(tǒng)中,經過編譯的C語言程序可以通過操作系統(tǒng)運行,也可以在沒有操作系統(tǒng)的情況下運行。程序存放的位置和運行的位置通常是不一樣的。一般情況下,經過編譯后的程序存儲在Flash或者硬盤中,在運行時需要將程序加載到RAM中。嵌入式系統(tǒng)的NorFlash和硬盤還有一定的差別,在硬盤的程序必須加載到RAM中才可以運行,但是在NorFlash中的程序可以通過XIP(
5、eXcutiveInPlace)的方式運行。在嵌入式系統(tǒng)中,C語言程序的運行包括3種類型:第一種是調試階段的程序運行,這個階段程序存放的位置和運行的位置是相同的;第二種是程序直接在Flash中運行(XIP);第三種是將Flash或者硬盤中的程序完全加載到RAM中運行。在C語言程序的運行中,存在著兩個基本的內存空間,一個是程序的存儲空間,另一個是程序的運行空間。程序的存儲空間必須包括代碼段、只讀數(shù)據(jù)段和讀寫數(shù)據(jù)段,程序的加載區(qū)域必須包括讀寫數(shù)據(jù)段和未初始化數(shù)據(jù)段如表13-3所示。表13-3C語言各部分使用的存儲空間段代碼只讀數(shù)據(jù)讀寫數(shù)據(jù)未初始化數(shù)據(jù)程序的存儲空間(ROM)需要不需要程序的加載空間
6、(RAM)不需要需要由于程序放入系統(tǒng)后,必須包括所有需要的信息,代碼表示要運行的機器代碼,只讀數(shù)據(jù)和讀寫數(shù)據(jù)包含程序中預先設置好的數(shù)據(jù)值,這些都是需要固化存儲的,但是未初始化數(shù)據(jù)沒有初值,因此只需要標示它的大小,而不需要存儲區(qū)域。在程序運行的初始化階段,將進行加載動作,其中讀寫數(shù)據(jù)和未初始化數(shù)據(jù)都是要在程序中進行“寫”操作,因此不可能放在只讀的區(qū)域內,必須放入RAM中。當然,程序也可以將代碼和只讀數(shù)據(jù)放入RAM。在程序運行后,堆和棧將在程序運行過程中動態(tài)地分配和釋放。13.4.1RAM調試運行本節(jié)介紹程序的一種特殊的運行方式,即在程序的調試階段將主機的映像文件直接放置到目標系統(tǒng)的RAM中。在這
7、種應用中,RAM既是程序的存儲空間,也是程序的運行空間。在嵌入式系統(tǒng)中,這是一種常用的調試方式,而不是通常的運行方式。在通常的運行方式下,程序運行的起始地址一般不可能是RAM。RAM在掉電之后內容會丟失,因此系統(tǒng)上電的時候,RAM中一般不會有有效的程序。但是在程序的調試階段,可以將程序直接載入RAM,然后在RAM的程序載入地址處運行程序。嵌入式系統(tǒng)RAM中的調試程序的內存布局如圖13-6所示。圖13-6RAM中的調試程序的內存布局這是一種相對簡單的形式,因為代碼段的存儲地址和運行地址是相同的,都是RAM(SDRAM或者SRAM)中的地址。在這種情況下,程序沒有運行初始化階段加載的問題。從主機向
8、目標機載入程序的時候,程序映像文件中代碼段(code或text)、只讀數(shù)據(jù)段、讀寫數(shù)據(jù)段依次載入目標系統(tǒng)RAM(SDRAM或者SRAM)的空間中。程序載入到目標機之后,將從代碼區(qū)的地址開始運行,在運行的初始化階段,將開辟未初始化數(shù)據(jù)區(qū),并將其初始化為0,在運行時將動態(tài)開辟堆區(qū)和棧區(qū)。在沒有操作系統(tǒng)的情況下,開辟內存的工作都是由編譯器生成的代碼完成的,實現(xiàn)的原理是在映像文件中加入這些代碼。主要工作包括:在程序運行時根據(jù)實際大小開辟未初始化的數(shù)據(jù)段;初始化棧區(qū)的指針,這個指針和物理內存的實際大小有關;在調用相關函數(shù)(malloc、free)時使用堆區(qū),這些函數(shù)一般由調用庫函數(shù)實現(xiàn)。表13-4列出了
9、C語言程序在RAM中的調試過程。表13-4C語言程序在RAM中的調試過程階段涉及的部分主要工作程序的映像代碼段(Code)只讀數(shù)據(jù)段(ROData)讀寫數(shù)據(jù)段(RWData)將程序放置在RAM中初始化階段未初始化數(shù)據(jù)段(BSS)開辟BSS段并且清零運行階段代碼段(Code)只讀數(shù)據(jù)段(ROData)讀寫數(shù)據(jù)段(RWData)未初始化數(shù)據(jù)段(BSS)堆(heap)棧(stack)運行RAM代碼段中的程序,動態(tài)地在RAM中開辟堆和棧知識點:程序直接載入RAM運行時,程序的加載位置和運行位置是一致的,因此不存在段復制的問題,需要在初始化階段開辟未初始化區(qū)域,在運行時使用堆棧。13.4.2固化程序的X
10、IP運行固化應用是一種嵌入式系統(tǒng)常用的運行方式,其前提是目標代碼位于目標系統(tǒng)ROM(Flash)中。ROM中的區(qū)域包括映像文件的代碼段(code或text)、只讀數(shù)據(jù)段(ROData)、讀寫數(shù)據(jù)段(RWData)。以XIP(在位置執(zhí)行)方式運行程序時內存布局如圖13-7所示。代碼的運行也是在ROM(Flash)中,因此,在編譯過程中代碼的存儲地址和運行地址是相同的,由于上電時需要啟動,因此該代碼的位置一般是(0 x0)。在這種應用中,一件重要的事情就是將已初始化讀寫段的數(shù)據(jù)從Flash中復制到SDRAM中,由于已初始化讀寫段既需要固化,也需要在運行時修改,因此這一步是必須有的,在程序的初始化階
11、段需要完成這一步。圖13-7XIP運行程序時的內存布局一般來說,在編譯過程中需要定義讀寫段和未初始化段的地址。在程序中可獲取這些地址,然后就可以在程序的中加入復制的代碼,實現(xiàn)讀寫段的轉移。表13-5列出了C語言程序的XIP運行過程。表13-5C語言程序的XIP運行過程階段涉及的部分主要工作程序的映像代碼段(Code)只讀數(shù)據(jù)段(ROData)讀寫數(shù)據(jù)段(RWData)程序放置在Flash中初始化階段讀寫數(shù)據(jù)段(RWData)未初始化數(shù)據(jù)段(BSS)復制讀寫數(shù)據(jù)段到RAM中開辟未初始化段并且清零運行階段代碼段(Code)只讀數(shù)據(jù)段(ROData)讀寫數(shù)據(jù)段(RWData)未初始化數(shù)據(jù)段(BSS)
12、堆(heap)棧(stack)運行Flash代碼段中的程序,動態(tài)地在RAM中開辟堆和棧知識點:程序在ROM或者Flash中以XIP形式運行的時候,不需要復制代碼段和只讀數(shù)據(jù)段,但是需要在RAM中復制讀寫數(shù)據(jù)段,并另辟未初始化數(shù)據(jù)段。13.4.3固化程序的加載運行在某些時候,在存放程序的位置是不能運行程序的,例如程序存儲在不能以XIP方式運行的Nand-Flash或者硬盤中,在這種情況下,必須將程序完全加載到RAM中才可以運行。固化程序加載運行的內存布局如圖13-8所示:HYPERLINK/files/uploadimg/20090226/150949757.jpg圖13-8固化程序加載運行的內
13、存布局依照這種方式運行程序,需要將Flash中所有的內容全部復制到SDRAM或者SRAM中。在一般情況下,SDRAM或者SRAM的速度要快于Flash。這樣做的另外一個好處是可以加快程序的運行速度。也就是說,即使Flash可以運行程序,將程序加載到RAM中運行也還有一定的優(yōu)勢。這樣做也產生了另外一個問題:代碼段的載入地址和運行地址是不相同的,載入地址是在ROM(Flash)中,但是運行的地址是在RAM(SDRAM或者SRAM)中。對于這個問題,不同的系統(tǒng)在加載程序的時候有不同的解決方式。C語言固化程序的加載運行過程如表13-6所示。表13-6C語言固化程序的加載運行時各段的情況階段涉及的部分主
14、要工作代碼的映像代碼段(Code)只讀數(shù)據(jù)段(ROData)讀寫數(shù)據(jù)段(RWData)將程序放置在Flash中初始化階段代碼段(Code)只讀數(shù)據(jù)段(ROData)讀寫數(shù)據(jù)段(RWData)未初始化數(shù)據(jù)段(BSS)加載代碼段和只讀數(shù)據(jù)段到RAM中復制讀寫數(shù)據(jù)段到RAM中開辟未初始化段并且清零運行階段代碼段(Code)只讀數(shù)據(jù)段(ROData)讀寫數(shù)據(jù)段(RWData)未初始化數(shù)據(jù)段(BSS)堆(heap)棧(stack)運行RAM代碼段中的程序,動態(tài)地在RAM中開辟堆和棧知識點:固化程序在加載運行時,需要復制代碼段、只讀數(shù)據(jù)段和讀寫數(shù)據(jù)段到RAM中,并另辟未初始化數(shù)據(jù)段,然后在RAM中運行程序
15、(執(zhí)行代碼段)。以這種加載方式的運行程序,另外一個重要的問題是:如何把代碼移到RAM中。在有操作系統(tǒng)的情況下,代碼的復制工作是由操作系統(tǒng)完成的,在沒有操作系統(tǒng)的情況下,處理方式相對復雜,程序需要自我復制。顯然,這種方式實現(xiàn)的前提是代碼最初放置在可以以XIP方式執(zhí)行的內存中。程序本身復制的過程也是需要通過程序代碼完成的,這時需要程序中的代碼根據(jù)將包含自己的程序從ROM或者Flash中復制到RAM中。這是一個比較復雜的過程,程序的最前面部分是具有復制功能的代碼。系統(tǒng)上電后,從ROM或者Flash起始地址運行,具有復制功能的代碼將全部代碼段和其他需要復制的部分復制到RAM中,然后跳轉到RAM中重新運
16、行程序。固化程序加載復制和跳轉過程如圖13-9所示。圖13-9固化程序加載復制和跳轉過程在代碼的前面一小部分是初始化的內容,這部分內容中有一部分是復制程序,這段復制程序將代碼段復制至RAM中,當這段初始化程序運行完成后,將跳轉到RAM中的某個地址運行。13.4.4C語言程序的運行總結在上面幾節(jié),主要介紹了C語言運行時內存的使用情況。其關注點是程序中主要的段,事實上,程序可能不僅包括了上述主要段,還可能包括一些頭信息。程序實際的運行也分為在操作系統(tǒng)下運行和直接運行等情況。在具有操作系統(tǒng)的情況下,程序由操作系統(tǒng)加載運行,加載的時候可執(zhí)行程序可以是一個文件,這個文件將包含程序的主要段以及頭信息。對于Linux操作系統(tǒng),目標程序是可執(zhí)行的ELF(ExecutableandlinkingFormat)格式;對于uCLinux操作系統(tǒng),目標程序是Flat格式;對于需要在系統(tǒng)直接運行的程序,目標程序應該是純粹的二進制代碼
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年廣東省建筑安全員-C證考試(專職安全員)題庫及答案
- 2025貴州省建筑安全員-C證考試(專職安全員)題庫附答案
- 2025山東省安全員知識題庫及答案
- 2025河南省安全員-C證(專職安全員)考試題庫
- 食品加工的原料和材料-課件
- 中醫(yī)內科學-感冒
- 《教師節(jié)綜合實踐》課件
- 有機藥化實驗課件
- 《急腹癥寶力道》課件
- 《運籌學》整數(shù)規(guī)劃
- 《上海理工大學》課件
- 中職班主任培訓
- 2024-2030年中國觸摸顯示器商業(yè)計劃書
- 三只松鼠深度分析報告
- 公共關系理論與實務教程 課件 項目九-公共關系危機管理
- 大創(chuàng)賽項目書
- 2024年江蘇省學業(yè)水平合格性考試全真模擬語文試題(解析版)
- 獨家投放充電寶協(xié)議書范文范本
- 第六章 綠色化學與科技課件
- 小學三年級下冊數(shù)學(青島54制)全冊知識點總結
- 汽車修理業(yè)務受理程序、服務承諾、用戶抱怨制度
評論
0/150
提交評論