操作系统:程序的编译、链接、装入及地址转换
目錄
靜態編譯與動態編譯
程序鏈接
裝入時動態鏈接
運行時動態鏈接
程序裝入
靜態地址重定位
動態地址重地位
基本分頁存儲管理的地址變換
邏輯地址空間與物理地址空間
前言
在多道程序環境下,要使程序運行,必須先為之創建進程。而創建進程的第一件事,便是將程序和數據裝入內存。將一個用戶源程序變為一個可在內存中執行的程序,通常都要經過以下幾個步驟:
(1)?編譯,由編譯程序(Compiler)將用戶源代碼編譯成 CPU 可執行的目標代碼,產生了若干個目標模塊(Object? Module)(即若干程序段)。
(2)?鏈接,由鏈接程序 (Linker)將編譯后形成的一組目標模塊(程序段),以及它們所需要的庫函數鏈接在一起,形成一個完整的裝入模塊(Load? Module)。
(3)?裝入,由裝入程序(Loader)將裝入模塊裝入內存。
以下的內容主要是一些概念,很大一部分來源于湯子瀛的《計算機操作系統》。
?
?
靜態編譯與動態編譯
(1) 靜態編譯,就是編譯器在編譯可執行文件的時候,將可執行文件需要調用的對應靜態庫(.a或.lib)中的部分提取出來,鏈接到可執行文件中去,使可執行文件在運行的時候不依賴于動態鏈接庫。
(2) 動態編譯的可執行文件需要附帶一個動態鏈接庫,在執行的時候,需要調用對應動態鏈接庫的命令。所以其優點是縮小了執行文件本身的體積,另一方面是加快了編譯速度。缺點是簡單的程序,只用到了鏈接庫的幾條命令,也需要附帶一個相對龐大的鏈接庫。若計算機上沒有安裝相應的庫,則用動態編譯的可執行文件不能運行。
?
?
程序鏈接
源程序經過編譯后,可得到一組目標模塊,再利用鏈接程序將這組目標模塊鏈接,形成裝入模塊。根據鏈接時間的不同,可把鏈接分成如下三種:
(1) 靜態鏈接。在程序運行之前,先將各目標模塊及它們所需的庫函數,鏈接成一個完整的裝配模塊,以后不再拆開。把這種事先進行鏈接的方式稱為靜態鏈接方式。
(2) 裝入時動態鏈接。這是指將用戶源程序編譯后所得到的一組目標模塊,在裝入內存時,采用邊裝入邊鏈接的鏈接方式。
(3) 運行時動態鏈接。這是指對某些目標模塊的鏈接,是在程序執行中需要該(目標)模塊時,才對它進行的鏈接。
?
裝入時動態鏈接
用戶源程序經編譯后所得的目標模塊,是在裝入內存時邊裝入邊鏈接的,即在裝入一個目標模塊時,若發生一個外部模塊調用事件,將引起裝入程序去找出相應的外部目標模塊,并將它裝入內存,還要修改目標模塊中的相對地址。裝入時動態鏈接方式有以下優點:
(1) 便于修改和更新。對于經靜態鏈接裝配在一起的裝入模塊,如果要修改或更新其中的某個目標模塊,則要求重新打開裝入模塊。這不僅是低效的,而且有時是不可能的。若采用動態鏈接方式,由于各目標模塊是分開存放的,所以要修改或更新各目標模塊是件非常容易的事。
(2) 便于實現對目標模塊的共享。在采用靜態鏈接方式時,每個應用模塊都必須含有其目標模塊的拷貝,無法實現對目標模塊的共享。但采用裝入時動態鏈接方式,OS則很容易將一個目標模塊鏈接到幾個應用模塊上,實現多個應用程序對該模塊的共享。
?
運行時動態鏈接
在許多情況下,應用程序在運行時,每次要運行的模塊可能是不相同的。但由于事先無法知道本次要運行哪些模塊,故只能是將所有可能要運行到的模塊都全部裝入內存,并在裝入時全部鏈接在一起。顯然這是低效的,因為往往會有些目標模塊根本就不運行。比較典型的例子是作為錯誤處理用的目標模塊,如果程序在整個運行過程中都不出現錯誤,則顯然就不會用到該模塊。運行時動態鏈接方式,是對上述在裝入時鏈接方式的一種改進。這種鏈接方式是將對某些模塊的鏈接推遲到程序執行時才進行鏈接,亦即,在執行過程中,當發現一個被調用模塊尚未裝入內存時,立即由 OS 去找到該模塊并將之裝入內存,把它鏈接到調用者模塊上。凡在執行過程中未被用到的目標模塊,都不會被調入內存和被鏈接到裝入模塊上,這樣不僅可加快程序的裝入過程,而且可節省大量的內存空間。
?
?
程序裝入
在多道程序環境下,所得到的目標模塊的起始地址通常是從 0 開始的,程序中的其它地址也都是相對于起始地址計算的。此時應采用可重定位裝入方式,根據內存的當前情況,將裝入模塊裝入到內存的適當位置。?
?
靜態地址重定位
靜態地址重定位:是指在程序開始運行前,程序中指令和數據的各個地址均已完成重定位,即完成虛擬地址到內存地址映射。地址變換通常是在裝入時一次完成的,以后不再改變。
優點:無需硬件支持。
缺點:(1)?程序重定位之后就不能在內存中移動了。
(2)?要求程序的存儲空間是連續的,不能把程序放在若干個不連續的區域中。
?
動態地址重地位
動態地址重定位:不是在程序執行之前而是在程序執行過程中進行地址變換。更確切的說,是把這種地址轉換推遲到程序真正要執行時才進行,即在每次訪問內存單元前才將要訪問的程序或數據地址變換成內存地址。動態重定位可使裝配模塊不加任何修改而裝入內存。為使地址轉換不影響指令的執行速度,這種方式需要一個重定位寄存器的支持。
優點:(1) 目標模塊裝入內存時無需任何修改,因而裝入之后再搬遷也不會影響其正確執行,這對于存儲器緊縮、解決碎片問題是極其有利的。
(2) 一個程序由若干個相對獨立的目標模塊組成時,每個目標模塊各裝入一個存儲區域,這些存儲區域可以不是順序相鄰的,只要各個模塊有自己對應的定位寄存器就行。
缺點:需要硬件支持。
?
?
基本分頁存儲管理的地址變換
邏輯地址空間與物理地址空間
編譯后,每個目標模塊都從 0 號單元開始編址,稱為該目標模塊的邏輯地址(或相對地址)。當鏈接程序將各個模塊鏈接成一個完整的可執行目標程序時,鏈接程序順序依次按各個模塊的地址構成統一的從 0 號單元開始編址的邏輯地址。不同進程可以有相同的邏輯地址,因為這些相同的邏輯地址可以映射到主存的不同位置。
物理地址是指內存中物理單元的集合,它是地址轉換的最終地址,進程在運行時執行指令和訪問數據,最后都要通過物理地址從內存中存取。當裝入程序將可執行代碼裝入內存時,必須通過地址轉換將邏輯地址轉換成物理地址,這個過程稱為地址重定位。
地址變換將邏輯地址轉換為物理地址。通常在系統中設置一個頁表寄存器(PTR Page-Table Register),存放頁表在內存中起始地址 F 和頁表長度 M。進程在未執行時,頁表的起址和頁表長度放在進程控制塊(PCB)中,當進程被調度時,操作系統內核會把它們放在頁表寄存器中。
邏輯地址到物理地址變換的過程:
(1) 計算頁號 P 和頁內偏移量 W。
(2) 比較頁號 P 和頁表長度 M,如果 P >= M,則會拋出越界異常。
(3) 頁表中頁號 P 對應的頁表項地址 = 頁表始址 + 頁號 * 頁表項長度,取出該頁表項內容 b,即內存塊號。
(4) 計算實際物理地址 = b * L + W 。
在分頁存儲管理(頁式管理)系統中,只要確定了每個頁面的大小,邏輯地址結構就確定了。頁式管理中地址是一維的,即只要給出一個邏輯地址,系統就可以自動算出頁號、頁內偏移量兩個部分,并不需要顯示告系統這個邏輯地址中,頁內偏移量占多少位。基本地址變換結構需要訪問兩次內存:第一次訪問內存查找頁表;第二次訪問物理內存對應的內存單元。
總結
以上是生活随笔為你收集整理的操作系统:程序的编译、链接、装入及地址转换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Google Spanner:谷歌的全球
- 下一篇: 分布式事务——TCC 原理