程式的裝入和鏈結

2021-09-12 10:44:26 字數 2674 閱讀 4018

注:這是本人學習湯小丹等編寫的計算機作業系統(西安電子科技大學出版社)的學習筆記,因此許多引用**於此書,在正文中就不註明了!

程式在執行前需要經過以下步驟:編譯程式對源程式進行編譯生成目標程式.obj;鏈結程式將目標程式和需要的庫檔案鏈結在一起形成可執行程式.exe,即乙個完整的裝入模組;裝入程式將裝入模組裝入記憶體,然後執行。依次稱為程式的編譯、鏈結、裝入。

程式的裝入方式有三種:絕對裝入方式、可重定位裝入方式和動態執行時的裝入方式。

絕對裝入方式。適用系統小且僅執行單道程式的情況,此時很容易知道程式裝入後將留在記憶體的什麼位置,因此程式經編譯後將產生含有絕對位址(實體地址或記憶體位址)的目標**,裝入程式將按照該位址裝入記憶體,因此裝入記憶體後程式的實際位址(記憶體位址)與程式的邏輯位址完全相同,不需要進行位址變換。程式中所使用的絕對位址既可以在編譯或彙編時指出(將程式中的符號位址轉變為絕對位址),也可以由程式設計師直接賦予(用絕對位址程式設計),但要求程式設計師熟悉記憶體的使用情況。

可重定位裝入方式。使用者程式編譯鏈結後形成的可執行程式的起始位址一般都是從0開始的,其它位址都是相對於起始位址計算的(邏輯位址),因此此時裝入後的實際位址與程式中的邏輯位址不同,需要進行位址變換。對於多道程式採用基址定址,有效位址ea=a+(br),a為指令的位址碼字段,br為基址暫存器,其內容由os和系統管理程式決定,值不變,系統根據br的值為程式分配儲存空間,因此裝入後需要根據該值進行位址變換,即程式中的邏輯位址(或虛擬位址)加上基址即可,對於程式中的資料位址(語句中引用到的邏輯位址)和外部呼叫符號都要進行相應的修改,即需要對程式位址(指令位址)、資料位址和外部呼叫符號進行修改。把在裝入時對目標程式中指令和資料位址的修改過程稱為重定位,對於可重定位裝入方式,該位址變換是一次完成的,以後不可以再修改,因此稱為靜態重定位。變址定址,ea=a+(ix),ix為變址暫存器,此時ix的值可變,由使用者設定,a的值不變,通常為陣列的起始位址。變址定址用於處理陣列問題,編制迴圈程式;相對定址,ea=(pc)+a,常用於轉移類指令,無論該程式在主存的哪乙個區域都可以正確執行,對於編寫浮動程式非常有利。

動態執行時的裝入方式。如果程式在記憶體中會發生移動,此時物理位置會發生變化,因此可重定位裝入方式不再適用,移動後需要再次對位址進行修改,如在具有對換功能的系統中,乙個程序可能會被多次換入和換出,其位置總是在發生變化,此時可採用動態執行時的裝入方式。該方式,將裝入模組裝入記憶體後,並不立即把裝入模組中的邏輯位址(虛擬位址)變換為實體地址,而是把這種位址變換過程推遲到真正執行時進行,即執行時通過:ea=a+(br)來完成位址變換,因此裝入模組的位址實際上一直都是邏輯位址(虛擬位址),程式執行時自動根據該位址進行變換,此時在cpu中需要設定乙個基址暫存器br,對於每乙個程序,os都會為其分配乙個基址。

鏈結程式的功能是將一組目標程式和需要的庫檔案鏈結成乙個完成的裝入模組,根據進行鏈結的時間不同分為三種鏈結方式:靜態鏈結方式、裝入時動態鏈結、執行時動態鏈結。

靜態鏈結方式。在裝入之前就將所有的目標模組和需要的庫檔案鏈結成為乙個完整的裝入模組(可執行檔案.exe),以後不再拆開。每個目標模組都採用的是邏輯位址,即起始位址均為0,因此鏈結過程中需要做以下修改:對相對位址(程式或指令位址、資料位址)進行修改;對外部呼叫符號進行修改,如callb,表示呼叫模組b(目標檔案b),改為jsr「l」,l為b的首位址。如下:

裝入時動態鏈結。對於各個目標模組和庫檔案採用邊裝入邊鏈結的方式,即在裝入乙個目標模組時,若發生乙個外部呼叫事件,將引起裝入程式去找出相應的外部呼叫模組,並將其裝入記憶體,然後進行鏈結,並按照上圖所示的方式修改位址。該方式具有以下優點:1.便於對目標模組修改和更新。對於經過靜態鏈結裝配在一起的裝入模組,如果要修改或更新某個目標模組,需要將其拆開,低效且麻煩,而且有時不可能。對於動態鏈結方式(裝入時動態鏈結和執行時動態鏈結),模組是分開存放的,對於修改和更新很容易實現(注意即使裝入了的模組,原模組依然存在,相當於拷貝乙份裝入)。2.便於實現目標模組的共享。對於靜態鏈結方式,每個應用模組都必須含有其目標模組的拷貝,無法實現對目標模組的共享。而動態鏈結方式卻可以容易將乙個目標模組鏈結到幾個應用模組上。

執行時動態鏈結。其是對裝入時動態鏈結方式的一種改進。這種鏈結方式是,將對某些模組的鏈結推遲到程式執行時才進行。亦即,在執行過程中,當發現乙個被呼叫模組尚未裝入記憶體時,立即由os去找到該模組,並將之裝入記憶體,將其鏈結到呼叫者模組上。凡在執行過程中未被用到的目標模組(如處理錯誤用的模組,如果執行過程中不出現錯誤,則不會用到),都不會被調入記憶體和被鏈結到裝入模組上,這樣不僅能加快程式的裝入過程,而且可節省大量的記憶體空間

在執行時進行鏈結,通常被鏈結的共享**稱為動態鏈結庫(dll, dynamic link library)或共享庫(shared library

程式的裝入和鏈結

編譯 鏈結 裝入 編譯 預處理 編譯 優化 彙編 靜態鏈結 動態鏈結 1 靜態鏈結 2 裝入時動態鏈結 3 執行時動態鏈結 裝入 靜態裝入 動態裝入 1 絕對裝入方式 這種方式在編譯的時候就會產生絕對位址 程式中的邏輯位址就是實際的實體地址 在裝入的時候不需要對位址和資料進行修改。缺點 只能將目標模...

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

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

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

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