物聯網學習教程—Linux 可執行檔案結構與程式結構
Linux
可執行檔案結構與程式結構
一、Linux可執行檔案結構
在 Linux 下,程式是一個普通的可執行檔案,以下列出一個二進位制可執行檔案的基本情況:
可以看出,此可執行檔案在儲存時(沒有調入到內容)分為程式碼區(text)、資料區(data)和未初始化資料區(bss)3 個部分。各段基本內容說明如下:
程式碼區:
存放 CPU 執行的機器指令。通常程式碼區是可共享的(即另外的執行程式可以呼叫它),使其可共享的目的是對於頻繁被執行的程式,只需要在記憶體中有一份程式碼即可。程式碼區通常是隻讀的,使其只讀的原因是防止程式意外地修改了它的指令。另外,程式碼區還規劃了區域性變數的相關資訊。
程式碼區的指令包括操作碼和操作物件(或物件地址引用)。如果是立即數(即是具體的數值),將直接包含在程式碼中,如果是區域性資料,將在執行時在棧區分配空間,然後再引用該資料的地址,如果是未初始化資料區和資料區,在程式碼中同樣將引用該資料的地址。
全域性初始化資料區/靜態資料區(資料段):
該區包含了在程式中明確被初始化的全域性變數、已經初始化的靜態變數(包括全域性靜態變數和區域性靜態變數)和常量資料(如字串常量)。
例如,一個不在任何函式內宣告(全域性變數),如下:
int count = 100;
使得變數 count 根據其初始值被儲存初始化資料區中。
在任意位置定義靜態變數方式如下:
static int num = 200;
這宣告瞭一個靜態資料並初始化,如果在任意函式體外宣告,則表示其為一個靜態全域性變數,如果在函式體內(區域性),則表示其為一個區域性靜態變數。另外,如果在一個函式名前加上 static,則表示此函式只能再當前檔案中被呼叫。
未初始化資料區(又叫 BSS 區):
存入的是全域性未初始化變數和未初始化靜態變數。未初始化資料區的資料在程式開始執行之前被核心初始化為 0 或者空(NULL)。
例如,一個不在任何函式內宣告的未初始化變數。
long sum[1000];
將 sum 儲存到未初始化資料
二、Linux程式結構
在 Linux 系統下,如果將某個可執行檔案載入到記憶體執行,則將演變成一個或多個程式(多個程式的原因是程式在執行時可以再建立新的程式,但載入時只有一個程式)。程式是 Linux 事務管理的基本單元,所有的程式均擁有自己獨立的處理環境和系統資源。程式的環境由當前系統狀態及其父程式資訊決定和組成的。
下圖為可執行檔案儲存結構和 Linux 程式基本結構(部分)的對照圖。
一個程式是一個執行著的程式段,一個程式主要包括在記憶體中申請的空間,程式碼(載入的程式,包括程式碼段,資料段,BSS),堆,棧,以及核心提供的核心程式資訊結構體
task_struct (位置在 /usr/include/linux/sched.h)、開啟的檔案、上下文(指程式執行活動全過程的靜態描述)資訊以及掛起的訊號等。
(1)程式碼區(text segment)。載入的是可執行檔案程式碼段,其載入到記憶體中的位置由載入器完成。
(2)全域性初始化資料區/靜態資料區(Data Segment)。載入的是可執行檔案資料段,儲存於資料段(全域性初始化,靜態初始化資料)的資料的生存週期為整個程式執行過程。
(3)未初始化資料區(BSS)。載入的是可執行檔案BSS段,位置可以分開亦可以緊靠資料段,儲存於資料段的資料(全域性未初始化,靜態未初始化資料)的生存週期為整個程式執行過程。
(4)棧區(stack)。由編譯器自動分配釋放,存放函式的引數值、返回值、區域性變數等。在程式執行過程中實時載入和釋放,因此,區域性變數的生存週期為申請到釋放該段棧空間。
(5)堆區(heap)。用於動態記憶體分配。堆在記憶體中位於BSS區和棧區之間。一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時有可能由OS回收。
系統之所以分成這麼多個區域,主要基於以下考慮:
程式碼段和資料段分開,執行時便於分開載入,在哈佛體系結構的處理器將取得更好得流水線效率。
程式碼時依次執行的,是由處理器 PC 指標依次讀入,而且程式碼可以被多個程式共享,資料在整個執行過程中有可能多次被呼叫,如果將程式碼和資料混合在一起將造成空間的浪費。
臨時資料以及需要再次使用的程式碼在執行時放入棧中,生命週期短,便於提高資源利用率。
堆區可以由程式設計師分配和釋放,以便使用者自由分配,提高程式的靈活性。
C 各儲存型別比較
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69914734/viewspace-2654120/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Linux可執行檔案格式-ELF結構詳解Linux
- 物聯網學習教程——執行緒池執行緒
- 物聯網學習教程—定義結構體型別變數的方法結構體型別變數
- 物聯網學習教程—檔案的定位
- 物聯網學習教程——執行緒同步與互斥:讀寫鎖執行緒
- 物聯網學習教程—— 執行緒私有資料執行緒
- 物聯網學習教程—檔案的讀寫二
- 物聯網學習教程—檔案的讀寫一
- Linux檔案結構Linux
- JVM學習--Class類檔案結構JVM
- Vue原始碼閱讀 – 檔案結構與執行機制Vue原始碼
- Vue原始碼閱讀 - 檔案結構與執行機制Vue原始碼
- PE檔案結構複習
- 物聯網學習教程—字串與指標字串指標
- 物聯網學習系列教程
- Linux 學習筆記--目錄結構及檔案基本操作Linux筆記
- linux檔案目錄結構彙總!Linux學習Linux
- linux下的檔案結構Linux
- 類檔案結構_class類檔案的的結構
- Linux學習之linux檔案目錄結構彙總Linux
- Xamarin XAML語言教程XAML檔案結構與解析XAML
- 物聯網學習教程——if語句
- 【LINUX學習】連結檔案Linux
- 二、Linux檔案系統結構Linux
- 物聯網學習教程—Linux系統程式設計之程式介紹Linux程式設計
- BMP檔案結構
- 資料結構學習之樹結構資料結構
- 物聯網學習教程——格式輸入與輸出
- Linux學習——2 目錄結構Linux
- jeesite檔案結構與jeesite.properties
- 深入學習Java虛擬機器——類檔案結構Java虛擬機
- 結構體學習結構體
- 物聯網學習教程——switch語句
- 物聯網學習教程——if語句2
- Linux檔案系統目錄結構Linux
- Linux下的檔案系統結構Linux
- 收藏資料結構學習網站資料結構學習網站
- 物聯網學習教程— 多維陣列與指標陣列指標