首頁 > 易卦

程式怎麼在系統中執行,詳細解讀程式在系統中的裝入和連結

作者:由 地球科技那點事 發表于 易卦日期:2022-05-19

執行一個程式要載入到記憶體的哪裡

我們平時運用計算機,主要就是使用使用者程式,而使用者程式要在系統中執行,必須將它裝入記憶體,然後轉換成一個可執行的程式。步驟如下:編譯,由編譯程式對使用者源程式進行編譯,形成若干個目標模組。連結,有連結程式將編譯後形成的一組目標模組以及它們所需要的庫函式連結在一起,形成一個完整的裝入模組。裝入,由裝入程式將裝入模組裝入記憶體。

程式的連結,源程式經過編譯後,可得到一組目標模組。而連結程式的功能就是將這組目標模組以及它們所需要的庫函式裝備成一個完整的裝入模組。而連線方式又可分為三種。

程式怎麼在系統中執行,詳細解讀程式在系統中的裝入和連結

靜態連結方式,在程式執行前先將目標模組以及它們所需的庫函式連結成一個完整的裝配模組,不過需要解決兩個重要問題:

對相對地址進行修改

,在編譯程式所產生的所以目標模組中,使用的都是相對地址,起始地址都為0,每個模組中的地址都是相對於起始地址計算的。所以就需要對後面模組的地址加上它自身的長度,在後面的模組依次累加。

變換外部呼叫符號

,將每個模組中所用的外部呼叫符號也都變換為相對地址。我們通常將這種事先連結而不拆開的連結方式稱為靜態連結方式。

程式怎麼在系統中執行,詳細解讀程式在系統中的裝入和連結

裝入時動態連結方式,將使用者源程式編譯後所得到的一組目標模組裝入記憶體時,採用邊裝入邊連結方式。即在裝入一個目標模組時,若發生外部模組呼叫事件,將引起裝入程式去找出相應的外部目標模組,並將它裝入記憶體。這種方式具有兩點優勢:

便於修改和更新

,對於靜態連結裝配在一起的裝入模組,如果需要修改或更新其中的某個目標模組,要求重新開啟裝入模組。而動態連結時的各個目標模組時彼此分開的,所以更新或修改是件非常容易的事。

便於實現對目標模組的共享

,在採用靜態連結方式時,每個應用模組都必須含有其目標模組的複製,而動態連結方式可以將一個目標模組連結到幾個應用模組上。

執行時動態連結方式,就是在執行過程中,當發現一個被呼叫模組尚未裝入記憶體時,立即由OS去找到該模組,並將之裝入記憶體,將其連結到被呼叫者模組上。未使用到的目標模組都不會被調入記憶體和被連結到裝入模組上,不僅能加快程式的裝入過程,而且可以節省大量的記憶體空間。

程式怎麼在系統中執行,詳細解讀程式在系統中的裝入和連結

而連結完成後的模組,我們就需要將他裝入記憶體了。程式裝入到記憶體,也有如下三種方式:

絕對裝入方式,使用者程式經編譯後,將產生絕對地址的目的碼,絕對裝入程式便可按照裝入模組中的地址,將程式和資料裝入記憶體。由於程式中的相對地址與實際記憶體地址完全相同,故不需要進行資料和地址的修改。

可重定位裝入方式,由於現代計算機大多數是在多程式環境下執行的,編譯程式不可能預知經編譯後所得到的目標模組應放在記憶體何處,因此編譯形成的若干目標模組中,它們的起始地址都是從0開始的,其他地址都是相對於起始地址計算的。而這種方法,它可以根據記憶體的具體情況將裝入模組裝入到記憶體的適當位置。這種在裝入時對目標程式中指令和資料地址的修改過程稱為重定位,而地址編會通常在程序裝入時一次完成,以後不再改變,故被稱為靜態重定位。

程式怎麼在系統中執行,詳細解讀程式在系統中的裝入和連結

動態執行時的裝入方式,動態執行時的裝入程式在把裝入模組裝入記憶體後,並不立即把裝入模組中的邏輯地址轉換為物理地址,而是把這種地址轉換推遲到程式真正要執行時才進行。

使用者程式轉換成可以執行的程式的過程大概如此,下一篇文章就會介紹關於程式在記憶體中的分配空間。