1. 程式人生 > 實用技巧 >一文搞定基址暫存器、界限暫存器、靜態重定位與動態重定位

一文搞定基址暫存器、界限暫存器、靜態重定位與動態重定位

地址空間是一個程序可用於定址記憶體的一套地址集合。每個程序都有一個自己的地址空間,並且這個地址空間獨立於其他程序的地址空間(除了在一些特殊情況下程序需要共享它們的地址空間外)。

給每個程式一個自己的地址空間,使得一個程式中的地址28所對應的實體地址與另一個程式中的地址28所對應的實體地址不同。方法:

基址暫存器與界限暫存器

使用一種簡單的動態重定位,把每個程序的地址空間對映到實體記憶體的不同部分。當使用基址暫存器和界限暫存器時,程式裝載到記憶體中連續的空閒位置且裝載期間無須重定位,如圖3-2c所示。當一個程序執行時,程式的起始實體地址裝載到基址暫存器中,程式的長度裝載到界限暫存器中。在圖3-2c中,當第一個程式執行時,裝載到這些硬體暫存器中的基址和界限值分別是0和16 384。當第二個程式執行時,這些值分別是16 384和16384。如果第三個16KB的程式被直接裝載在第二個程式的地址之上並且執行,這時基址暫存器和界限暫存器裡的值會是32 768和16 384。

每次一個程序訪問記憶體,取一條指令,讀或寫一個數據字,CPU硬體會在把地址傳送到記憶體匯流排前,自動把基址值加到程序發出的地址值上。同時,它檢查程式提供的地址是否等於或大於界限暫存器裡的值。如果訪問的地址超過了界限,會產生錯誤並中止訪問。這樣,對圖3-2c中第二個程式的第一條指令,程式執行

  1. JMP28

指令,但是硬體把這條指令解釋成為(28+16384=16412)

  1. JMP16412

所以程式如我們所願地跳轉到了CMP指令。在圖3-2c中第二個程式的執行過程中,基址暫存器和界限暫存器的設定如圖3-3所示。

圖3-2 重定位問題的說明:a) 一個16KB程式;b) 另一個16KB程式;c) 兩個程式連續地裝載到記憶體中

使用基址暫存器和界限暫存器是給每個程序提供私有地址空間的非常容易的方法,因為每個記憶體地址在送到記憶體之前,都會自動先加上基址暫存器的內容。在很多實際系統中,對基址暫存器和界限暫存器會以一定的方式加以保護,使得只有作業系統可以修改它們。

使用基址暫存器和界限暫存器重定位的缺點是,每次訪問記憶體都需要進行加法和比較運算。比較可以做得很快,但是加法由於進位傳遞時間的問題,在沒有使用特殊電路的情況下會顯得很慢。

程式執行時,必須將地址空間變為絕對地址才能訪問系統分配的記憶體

地址重定位:作業系統把使用者程式指令中的相對地址變換成為所在儲存中的絕對地址的過程

地址重定位實現了:從邏輯地址到實體地址的轉換

地址的靜態重定位

定義:在程式執行之前,為使用者程式實行了地址重定位工作

一般由作業系統中的重定位裝入程式完成

重定位裝入程式的輸入:使用者把自己的作業連結裝配成一個相對於 0 編址的目標程式

實現過程:

靜態重定位的處理方法為在載入程式到記憶體中時,將程式中所有的地址都加上在記憶體中的起始地址。比如一個程式被載入到從1000號開始的記憶體空間,而且程式中有一條指令JMP 28,那麼程式被載入入記憶體後這條指令會變成 JMP 1028。靜態重定位的難點在於區分程式中哪些值是常量,哪些值是地址。

特點:

  • 在裝入前實現調整
  • 地址要有標識
  • 每次裝入都要進行定位
  • 裝入後地址不再改變(靜態)

地址的動態重定位

定義:在程式執行定址時進行重定位,訪問地址時,通過地址變換機構改變為記憶體地址,使用者程式原封不動的裝入記憶體,執行時再完成地址的定位工作。動態重定位需要硬體的支援,要求系統中配備定位暫存器和加法器。

實現過程:

使用動態重定位的cpu有兩個特殊的暫存器:基址暫存器和界限暫存器。當一個程序執行時,程式的起始地址被裝載到基址暫存器中,程式的長度被裝載到界限暫存器中。當程式要進行記憶體操作時,cpu會首先將指令中的地址加上基址暫存器中的地址,再把地址送到記憶體匯流排。此外,cpu還會檢查地址是否大於界限暫存器中的值。如果訪問的地址超出了界限則會出錯並停止訪問。

特點:

  • 程式可裝入任意記憶體區域(不要求佔用連續的記憶體區)
  • 只裝入部分程式程式碼即可執行
  • 改變系統時不需要改變程式(程式佔用的記憶體空間動態可變,只需要改變定位暫存器中的值即可)
  • 程式可方便共享