1. 程式人生 > >【轉】地址重定位:靜態重定位和動態重定位

【轉】地址重定位:靜態重定位和動態重定位

一、靜態重定位
靜態重定位是在程式執行之前進行重定位,它根據裝配模組將要裝入的記憶體起始位置,直接修改裝配模組中的有關使用地址的指令。
  例如,一個以“0”作為參考地址的裝配模組,要裝入以100為起始地址的儲存空間。顯然,在裝入之前要做某些修改,程式才能正確執行。例如,MOV  EAX,[500]這條指令的意義,是把相對地址為500的儲存單元內容1234裝入EAX號累器。現在內容為1234的儲存單元的實際地址為1500, 即為相對地址(500)加上裝入的地址(1000),因此,MOV EAX,[500]這條指令中的直接地址碼也要相應地加上起始地址,而成為MOV  EAX,[1500]。
  程式中涉及直接地址的每條指令都要進行這樣的修改。需要修改的位置稱為重定位項,所做的加實際裝入模組起始地址修改中的塊起始地址稱為重定位因子。

  為支援靜態重定位,連線程式在生成統一地址空間和裝配模組時, 應產生一個重定位項表,連線程式此時還不知道裝配模組將要裝入的實際位置,故重定位表 所給出的需修改位置是相對地址所表示的位置。
  作業系統的裝入程式要把裝配模組和重定位項表一起裝入記憶體。由裝配模組的實際裝入起始地址得到重定位因子,然後實施如下兩步:
  (1)取重定位項,加上重定位因子而得到欲修改位置的實際地址;
  (2)對實際地址中的內容再做加重定位因子的修改,從而完成指令程式碼的修改。
  對所有的重定位項實施上述兩步操作後,靜態重定位才完成,爾後可啟動程式執行。使用過的重定位項表記憶體副本隨即被廢棄。
靜態重定位有著無需硬體支援的優點,但存在著如下的缺點:一是程式重定位之後就不能在記憶體中搬動了;二是要求程式的儲存空間是連續的,不能把程式放在若干個不連續的區域內。


二、動態重定位
動態重定位是指,不是在程式執行之前而是在程式執行過程中進行地址重定位。更確切地說,是在CPU每次訪問記憶體單元前才進行地址變換。動態重定位可使裝配模 塊不加任何修改而裝入記憶體,但是它需要硬體——定位暫存器的支援。
  程式的目標模組裝入記憶體時,與地址有關的各項均保持原來的相對地址不進行任何修改。如MOV 1,[500]這條指令仍是相對地址500。當此模組被 作業系統排程到處理機上執行時,作業系統將把此模組裝入的實際起始起始地址減去目標模組的相對基地址,然後將其差值裝入定位暫存器中。當CPU取得一條訪 問記憶體的指令時,地址變換硬體邏輯自動將指令中的相對地址與定位暫存器中的值相加,再依此和值作為記憶體絕對地址去訪問該單元中的資料。

  由此可見,進行動態重定位的時機是在指令執行過程中,每次訪問記憶體前動態地進行。採取動態重定位可帶來兩個好處:
  (1)目標模組裝入記憶體時無需任何修改,因而裝入之後再搬遷也不會影響其正確執行,這對於儲存器緊縮、解決碎片問題是極其有利的;
  (2)一個程式由若干個相對獨立的目標模組組成時,每個目標模組各裝入一個儲存區域,這些儲存區域可以不是順序相鄰的,只要各個模組有自己對應的定位暫存器就行。