此部分內容,參看了《嵌入式linux上的c語言程式設計實踐》一書第13章的部分內容。
由c語言**(文字檔案)形成可執行程式(二進位制檔案),需要經過編譯-彙編-連線三個階段。編譯過程把c語言文字檔案生成匯程式設計序,彙編過程把匯程式設計序形成二進位制機器**,連線過程則將各個原始檔生成的二進位制機器**檔案組合成乙個檔案。
c語言編寫的程式經過編譯-連線後,將形成乙個統一檔案,它由幾個部分組成。在程式執行時又會產生其他幾個部分,各個部分代表了不同的儲存區域:
**段由程式中執行的機器**組成。在c語言中,程式語句進行編譯後,形成機器**。在執行程式的過程中,cpu的程式計數器指向**段的每一條機器**,並由處理器依次執行。
唯讀資料段是程式使用的一些不會被更改的資料,使用這些資料的方式類似查表式的操作,由於這些變數不需要更改,因此只需要放置在唯讀儲存器中即可。
已初始化資料是在程式中宣告,並且具有初值的變數,這些變數需要占用儲存器的空間,在程式執行時它們需要位於可讀寫的記憶體區域內,並具有初值,以供程式執行時讀寫。
未初始化資料是在程式中宣告,但是沒有初始化的變數,這些變數在程式執行之前不需要占用儲存器的空間。
堆記憶體只在程式執行時出現,一般由程式設計師分配和釋放。在具有作業系統的情況下,如果程式沒有釋放,作業系統可能在程式(例如乙個程序)結束後**記憶體。
棧記憶體只在程式執行時出現,在函式內部使用的變數、函式的引數以及返回值將使用棧空間,棧空間由編譯器自動分配和釋放。
c語言目標檔案的記憶體布局如圖所示。
**段、唯讀資料段、讀寫資料段、未初始化資料段屬於靜態區域,而堆和棧屬於動態區域。**段、唯讀資料段和讀寫資料段將在連線之後產生,未初始化資料段將在程式初始化的時候開闢,而堆和棧將在程式的執行中分配和釋放。
c語言程式分為映像和執行時兩種狀態。在編譯-連線後形成的映像中,將只包含**段(text)、唯讀資料段(ro data)和讀寫資料段(rw data)。在程式執行之前,將動態生成未初始化資料段(bss),在程式的執行時還將動態形成堆(heap)區域和棧(stack)區域。
一般來說,在靜態的映像檔案中,各個部分稱之為節(section),而在執行時的各個部分稱之為段(segment)。如果不詳細區分,可以統稱為段。
c語言在編譯和連線後,將生成**段(text)、唯讀資料段(ro data)和讀寫資料段(rw data)。在執行時,除了以上三個區域外,還包括未初始化資料段(bss)區域和堆(heap)區域和棧(stack)區域。
C語言開發總結(二十一)
c語言記憶體管理分析 歡迎進入記憶體這片雷區。偉大的bill gates 曾經失言 640k ought to be enough for everybody bill gates 1981 程式設計師們經常編寫記憶體管理程式,往往提心吊膽。如果不想觸雷,唯一的解決辦法就是發現所有潛伏的地雷並且排除...
c語言學習筆記二十一
makefile中關於變數的語法規則 示例 如下 foo bar bar huh?all echo foo 執行make後輸出 huh?優點 可以把變數的值推遲到後面定義 示例 main.o main.c cc cfags cppflags c cc gcc 編譯選項 cfags o g 預處理選項...
C 複習(二十一) 三個平方數
問題五十 將1 9九個數字分為三組三位數,每個數字只允許用一次,要求每組的三個數都組成乙個平方數 問題五十一 求解九位累計可除數,分別為1 9不重複,這個九位數的前n位剛好可以被n整除,求解這個九位數 問題五十 將1 9九個數字分為三組三位數,每個數字只允許用一次,要求每組的三個數都組成乙個平方數 ...