程式的鏈結與裝入(動 靜態重定位)

2021-06-18 15:32:08 字數 2383 閱讀 5666

多道程式環境下,程式是併發執行的,所以要使程式執行,必須先為之建立程序,而建立程序的第一件事就是將程式和資料裝入記憶體

源程式經過編譯後,得到一組目標模組,再利用「鏈結程式」將這組目標模組鏈結起來,形成乙個完整的裝入模組(即可執行檔案

ø相對位址進行修改(變化以後還是相對位址),位址都變為相對最上層模組的起始位址來計算。

ø變化外部呼叫符號,如call b------> jsr「l」

call b為呼叫b模組,jsr「l」為跳轉到l行

鏈結前a和b為兩個不同的模組,在a模組中想執行b模組,要使用呼叫(call)語句;鏈結後a和b為同一模組,若想達到同樣地效果,只需在本模組中使用跳轉語句(jsr)跳轉到想執行的地方即可。

即將鏈結好的模組裝入記憶體

使用者程式編譯為目標模組後,會對每個模組內部(程式資料等)進行編址,此時編好的位址叫做邏輯位址或相對位址(下面的絕對裝入方式除外),都是相對於本模組的起始位址(一般從0開始)計算的。進行鏈結後某些模組的相對位址會發生變化,位址都變為相對於裝入模組的起始位址進行計算。

通常將記憶體的實際位址稱為實體地址

ø  絕對裝入方式

ø  可重定位裝入方式(靜態重定位)

ø  動態執行時裝入方式(動態重定位)

程式編譯時,如果知道程式將駐留在記憶體的什麼位置(起始位址),那麼編譯生成的目標**,將採用絕地位址進行編址,即起始位址不從0開始,從上面所知的記憶體起始位址開始編址。

例如:事先已知使用者程式(程序)駐留在從1000號單元處開始的位置,則編譯程式所產生的目標模組(即裝入模組)便從1000處開始向上擴充套件:

由於採用的是絕對位址,所以將裝入模組直接裝入記憶體即可,無需進行位址變換。

ø  出現:

編譯時將程式裝入指定的記憶體空間,必須需要程式設計師熟悉記憶體的使用情況

絕對裝入方式只能將目標模組裝入到記憶體中事先指定的位置。而在多道程式環境下,編譯程式不可能預知所編譯的目標模組應放在記憶體的何處

可重定位方式可根據記憶體的當前情況,將裝入模組裝入到記憶體的適當位置

ø  原理:

源程式編譯生成的目標模組都採用相對位址進行編址,即每個模組都從0開始編址,當然鏈結後的模組也採用相對位址編址

將裝入模組裝入記憶體後,模組中的程式和資料等,在記憶體中都將具有乙個實體地址,此實體地址是相對於記憶體的起始位址進行編址的,所以與原先模組中的邏輯位址(相對於模組的起始位址進行編址)不同,所以為了得到實體地址需要對邏輯位址進行改變。而此位址變化的過程就叫做重定位,又因為位址變換通常是在裝入時一次完成的,以後不再改變,故稱為靜態重定位。如下圖:

只是把相對位址到絕對位址的轉換推遲到程式真正執行時才進行

程式的鏈結與裝入(動 靜態重定位)

多道程式環境下,程式是併發執行的,所以要使程式執行,必須先為之建立程序,而建立程序的第一件事就是將程式和資料裝入記憶體 即 源程式經過編譯後,得到一組目標模組,再利用 鏈結程式 將這組目標模組鏈結起來,形成乙個完整的裝入模組 即可執行檔案 相對位址進行修改 變化以後還是相對位址 位址都變為相對最上層...

程式的重定位問題(程式裝入)

摘自csdn部落格 原文 程式的裝入方式一般可分為以下3種 在編譯時,如果程式知道將駐留在記憶體的什麼位置,那麼,編譯程式將產生絕對位址的目標 絕對裝入方式按照裝入模組中的位址,將程式和資料裝入記憶體。裝入模組被裝入記憶體後,由於程式中的邏輯位址和實際記憶體位址完全相同,所以不需要對程式和資料的位址...

靜態鏈結 重定位

在幾年前第一次學c語言時,按照書上給的示例,在vc6.0中寫了helloworld程式,然後按照書上的教程,進行編譯,鏈結,最後執行程式,就能在輸出視窗上看到helloworld。對於乙個用ide寫 的人來說,需要編譯鏈結才能生成可執行檔案這是乙個常識,那麼編譯鏈結到底做了乙個什麼樣的事情呢?因為我...