1. 程式人生 > >Linux C的可執行檔案結構以及程序結構

Linux C的可執行檔案結構以及程序結構

1

(公共部分):程式碼區,BSS區,資料區.

1.程式碼區:存放可執行的指令.順便規劃局部變數的相關資訊(??).

  獨有性:一份指令在記憶體(不管虛擬記憶體還是實際)中只要有一份就可以的

  只讀性:彙編指令包含 操作碼+運算元;一般操作碼是不可變的,但是運算元可以改變.

而且有不同的定址方式.

立即數 資料包含在指令區
區域性資料 執行時在棧中分配,然後在指令中引用地址
BSS區,資料區 同上在,指令中引用"物件"的地址.

2靜態區:

    1.函式外的已初始化全域性變數(包括函式外部靜態變數).

 2.靜態變數.

至於static的訪問許可權問題老生長談:1.靜態變數執行時不會被"釋放"2.static限定本檔案訪問.

未初始化變數區(BSS Block Started by Symbol)

  未初始化的全域性變數和靜態變數.特點:被系統自動置NULL的指標(引用型別),或者被置0的基本數字型別.

在被載入到記憶體中執行的時候,以上三段都賦予了不同的特點.

程式碼段 由載入器確定,一般是由OS支援的,如果在OS外,要手動指定載入位置了.試想一下ueft和boot程式的記憶體位置是沒有OS支援的.
靜態區 生命週期為程式進入記憶體到釋放整個階段
BSS區 同靜態區

區域性變數,函式引數值,返回值等等.

Note:在堆疊出棧(函式執行結束)時失效,這就是為啥函式內變數不能被作用域外使用 以及 進行(地址引用:野指標的生產大戶)

管理者:編譯器管理.

特性:線性地址(地址連續,都有唯一前驅後繼)

用於動態分配記憶體.BSS區和棧區之間.

一般由User分配和釋放.(Java只由自己分配,釋放交JVM)

特性:非線性,可能產生記憶體碎片.

這樣分配的原因:

1.程式碼和資料分開,可以在哈弗架構下的CPU更高效.Code-Cache-Bus與Data-Cache-Bus分開並行工作.

2.同上,即使在馮諾依曼結構下,程式碼執行也是PC自加進行的.如果混編會破壞Code地址的線性特性,降低效率,(定位陣列和連結串列那個更快?)

3.臨時變數生命週期短,放在棧中有效提高效率.

4.堆可以使程式更具有靈活性.

配合修飾符

(懶得打字了直接上圖)

1

全域性變數,函式在外使用的方法:

  1.標頭檔案中定義:可能會產生重複定義(在連結階段*.o-->elf檔案時候).因為標頭檔案在處理的時候是copy到*.c/*.cc/*.cpp檔案內的,在編譯階段每個檔案(*.o)都會生成一個"該識別符號",而且作用域是整個工程.

     2.extern定義: