1. 程式人生 > >程式的連結與裝入(動、靜態重定位)

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

 原由:

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

   

目的:

   

使用者程式到記憶體可執行程式的步驟:

   

  即

   

下面開始將程式“連結”和“裝入”的具體情況:

程式的連結:

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

  如下圖:源程式編譯後得到三個目標模組A、B、C,長度分別為L、M、N,連結後形成右側的裝入模組:

   

  連結時需要做兩個工作:

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

  Ø  變化外部呼叫符號,如CALL B------> JSR“L”

  CALL B為呼叫B模組,JSR“L”為跳轉到L行

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

程式的裝入:

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

邏輯地址與實體地址

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

的起始地址進行計算。

    

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

       

分類

  Ø  絕對裝入方式

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

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

解析

 (1)絕對裝入方式

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

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

   

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

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

Ø  出現:

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

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

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

Ø  原理:

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

   

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

   

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

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

總結: