通過乙個可執行檔案被執行的過程理解程序的深刻性

2021-06-27 00:55:24 字數 1990 閱讀 1509

不知大家在平時想過沒有,我們放在磁碟(之前我一直認為windows的c

盤是主存,

def盤是磁碟,哈哈,應該沒有像我這樣無知的人吧)上的乙個可執行檔案(或者應用程式)是如何得到執行的,而且為什麼我們在寫程式的時候怎麼感覺程式中的一些變數的位址好像在各個不同的程式中都差不多,同時這個位址到底真正對應的是什麼?是我們可執行檔案對應所在位置的磁碟位址嗎?下面我就以

linux

為平台(

windows

在linux

中當我們開啟

shell

時,我們相當於已經新建了乙個程序,這個程序執行的是

shell

這個應用程式。當在

shell

中輸入乙個可執行目標檔案的名字時,

shell

會用fork()

函式建立乙個新的程序,在這個新程序中呼叫

execve()

函式來載入和執行這個可執行檔案。

我準備詳細來說明一下這個execve()

函式是如何來工作的,比如它是如何將磁碟上的目標檔案拷貝到主存中來讓

cpu執行的?程式中我們所看到的位址到底是什麼?帶著這些問題我們來一步一步分析。

首先因為execve()

函式是在

shell

這個程序的子程序中執行的,而子程序必定會拷貝(其實也不是拷貝,要不然這個程序設計的也太臃腫了,是一種叫寫時拷貝的機制)很多父程序已存在的內容,所以必須刪除掉。

然後它開始對映(看到對映有沒有想到數學中叫函式對映的東西,本質上都是一樣的)我們可執行檔案中的內容,談到對映那必然是x------%26gt;y

,現在y

是我們的可執行檔案,那

x呢?先給大家補充一點程序中的知識,等補充完了,才能說

x。每個程序中都有乙個叫頁表的東西,頁表有很多項,每一項叫頁表項(為了簡化問題的複雜性我們就假設

linux

是一級頁表吧),同時在作業系統中一般乙個頁或者物理塊的大小為

4kb(對應為

12位的頁內位址),所以在乙個

32的作業系統中只需要儲存

2^20

個頁表項就可以表示位址從

0x00000000

到0xffffffff

的範圍,其中這個位址的後

12位為頁內位址,而我們在程式中所見到的位址就是這個位址,根本不是什麼我們程式對應的實體地址。記住,這個位址並不是真正對應的磁碟或者記憶體的位址,而是虛擬的,叫虛擬位址。如果現在還不太明白等我全部講完就會懂的。

講到這裡大家先稍微理解理解,免得看的一頭霧水。那我開始,剛剛我們說到程序中的頁表項,每乙個頁表項從開始到結束對應的編號為0x00000-0xfffff

(一共2^20

個,大家可以畫一畫),這個頁表項主要有兩個部分,第乙個部分用來指向磁碟的物理塊或者記憶體上的塊,第二個部分表明所指向的塊是在磁碟上還是記憶體上或者這部分就根本沒用。

那麼我們現在可以說x

是什麼了,就是虛擬位址!說完了x,

y,那還有對映規則呢,對於我們程式中的文字塊,資料塊,棧,堆等在

linux

中分別對應不同的虛擬位址,而且是固定的,對所有程式都一樣。這也就可以解釋為什麼不同的程式不同的變數有時候位址卻差不多,因為他們的虛擬位址都是從

0x00000000---0xffffffff

,因此當他們的變數都儲存在棧中時,對應的虛擬位址也很接近。

對映完之後,execve()

呼叫啟動**,啟動**將呼叫

main()

函式,大家一定會想現在可執行目標不是還在磁碟上嗎?它是怎麼拷貝到記憶體上,然後被

cpu執行的呢?確實如此,因此當啟動**將

main()

函式的虛擬位址傳遞給

cpu時,

cpu通過解析虛擬位址發現記憶體中沒有

main()

相對應的頁或者物理塊,然後

cpu通過程序中的頁表項找到我們可執行檔案所在的磁碟位置,將磁碟上的塊拷貝到記憶體中,這樣

cpu就可以順利的執行我們的程式了。

通過乙個可執行檔案被執行的過程理解程序的深刻性

不知大家在平時想過沒有,我們放在磁碟 之前我一直認為windows的c 盤是主存,def盤是磁碟,哈哈,應該沒有像我這樣無知的人吧 上的乙個可執行檔案 或者應用程式 是如何得到執行的,而且為什麼我們在寫程式的時候怎麼感覺程式中的一些變數的位址好像在各個不同的程式中都差不多,同時這個位址到底真正對應的...

linux 如何執行乙個可執行檔案

本文只為整理思路,供自己日後參考。現在就從從乙個執行檔案a.out的執行開始,自上而下地分析linux是如何執行乙個執行檔案的。1 首先,需要了解一下a.out這個目標檔案。a.out在linux下是elf executable linkable format 檔案格式,該目標檔案由乙個檔案頭 段 ...

生成可執行檔案過程

c語言編譯全過程 編譯的概念 編譯程式讀取源程式 字元流 對之進行詞法和語法的分析,將高階語言指令轉換為功能等效的彙編 再由匯程式設計序轉換為機器語言,並且按照作業系統對可執行檔案格式的要求鏈結生成可執行程式。編譯的完整過程 c源程式 預編譯處理 c 編譯 優化程式 s asm 匯程式設計序 obj...