1. 程式人生 > >深入理解程式的結構

深入理解程式的結構

 

程式的構成:從作業系統的角度來看

 

檔案頭記錄了與可執行檔案相關的一些基本資訊。

靜態分析工具大多根據程式的檔案頭獲得相關資訊。

初始化的變數進入.data段,沒有初始化的全域性變數進入.bss段。

 

 

 

 

未初始化的變數預設為0,為了儲存效率和載入效率。

 

 

沒有初始化的預設為0,在程式檔案中就不用儲存初始值了,只需在程式檔案中記錄:有幾個全域性變數,以及它們的型別。

而data段要儲存初始值。

實驗分析:

程式碼如下:

 

做如下編譯:

-e指明程式入口,-nostartfiles說明不使用程式自帶的那些啟動檔案。

使用objdump可以檢視程式有哪些段:

 

 

1、2這兩個段是gnu系統特有的輔助段,7這個段也是可以去掉的。 最重要的就是.text段。我們這個程式中沒有資料段。

 

改寫程式:

 

 

objdump結果如下:

.data和.bss段都有了。

改程式設計序:

 

objdump結果如下:

 

編譯器預設按4位元組對齊,因此bss段還是佔用8位元組。

將程式改成如下形式就佔用4個位元組了:

 

 

使用nm檢視符號:

 

 

 

dt_main和text段的初始地址正好對應上。

g_no_value在bss段,其中的B代表bss。g_value在data段,D代表data。

c_no_value和bss的起始地址是一致的。

c_no_value之後就是g_no_value。

用objdump檢視data段中儲存的初始值資訊:

 

 

上圖表示從8049ff4開始儲存了01000000  02000000

改造程式:

 

 編譯之後objdump結果如下:

 

data段的位元組數是21,4位元組對齊之後data段的大小應該是24,圖中顯示的18是16進位制。正好等於十進位制的24。

nm檢視符號:

 

可以看到多了一個符號g_str。

再次改寫程式:

 

objdump結果和nm結果:

 

 

g_c的記憶體地址正是rodata段的起始地址。

檢視rodata段的內容: