虛存與主存的地址對映方法詳解
為最近在寫系統命令的時候,經常會出現段錯誤。但是段錯誤的提示資訊一般情況下是比較少的,所以斷錯誤並不是很好找。前幾天從網上查詢了關於段錯誤的一些資料,發現一般段錯誤基本都是與記憶體有關,比如有:訪問不存在的記憶體地址,訪問只讀的記憶體地址,以及訪問被系統保護的記憶體地址。通過dmesg命令可以檢視發生段錯誤的程式名稱、引起段錯誤發生的記憶體地址、指令指標地址、堆疊指標地址、錯誤程式碼、錯誤原因等。所以我打算將儲存之間的對映這一塊的知識作以較為詳細的說明,會用我自己的理解來說的明白些。
先說說虛存與記憶體的對映,因為一般情況下,我們寫的程式碼都是在虛存上,但是當代碼需要執行的時候就必須將其裝入記憶體,所以就必須將虛存的地址以一定的規則轉換成實地址。
虛存的地址變換,分三種:段式,頁式,段頁式。 很明顯,有段頁式,說明段式和頁式各有優缺點。
一. 段式
段式虛擬儲存器,當我們編寫程式的時候,一般會把程式分成段,常見的有資料段DS,程式碼段CS,附加段ES和堆疊段SS。這些段的長度都是不一的。多使用者虛地址是由使用者號U,段號S,和段內偏移地址D組成的。虛地址和實地址之間是通過段表(存放於主儲存器)來映像的,CPU中會有一個段表基址暫存器,段表記錄:段號,段長,起始地址。從基址暫存器能夠直接讀出段表的起始地址。通過使用者號U查詢到對應的基址暫存器,基址暫存器的起始地址加上虛地址的段號,就能找到段表地址,然後如果所訪問的段在記憶體中,則從段表中給出的起始地址,加上虛地址的偏移量,則就得到實地址。(計算兩次)
模組化效能好,便於連結和排程,但地址變換花費時間長,記憶體利用率低(段大小不一,會浪費空間)。
二. 頁式
使用者虛地址由:使用者號U,虛頁號P,和頁內偏移地址D組成。因為頁的大小都是固定的,所以這兒只需要進行一次運算,和段表相對,頁表用來記錄頁號和主存頁號,CPU中的基址暫存器存放頁表的基地址,和段表一樣,使用者號U會通過基址暫存器找到頁表起始地址,起始地址與虛頁號相加,再與偏移地址拼接就得到實地址,因為頁的大小是一樣的,所以它在虛地址中某一頁的偏移量和主存中某一頁的偏移量是一樣的。(計算一次)
主存利用率高,只有最後一頁會存在浪費的情況。管理也容易。模組化效能不好(因為有可能一個程式的某一段會被分在好幾頁上)
三. 段頁式。
對使用者用段式管理,對記憶體用分頁式管理。段表記錄:頁表長度和頁表地址。虛地址由:使用者號U,段號S,虛頁號P,頁內偏移D組成。先通過U在段表基址暫存器中找到段表基地址,然後和段號S相加,得到頁表起始地址和頁表長度,通過頁表找到主存實頁號再與偏移量拼接,得到實地址。(頁表的長度就是頁表數)
如果要訪問的地址不在記憶體中,就會需要調入一頁或一段到主存中。