我記得大學的彙編課程、組成原理課裡老師講過實模式和保護模式的區別,在很多書本上也有談及,無奈本人理解和感悟能力實在太差,在很長一段時間裡都沒真正的明白它們的內含,更別說為什麼實模式下最大定址空間為1mb?段的最大長度不超過64kb?而保護模式下為啥最大定址能力就變成了64tb?每個段最大也達4gb? 更甚者分段和分頁這兩個高深的概念像我這種菜鳥怎麼也理解不了啊!
定址能力都達64tb了,為啥我的電腦記憶體只有2gb呢?其實不用糾結於這事,這64tb就是所謂的虛擬位址空間,也叫邏輯位址空間,它能夠定址這麼多,只是它有這個能力,並不代表你的記憶體就要裝這麼大,你記憶體比它小再多也不會影響你工作,反過來,要是它的定址能力只有1mb,而你有2gb的記憶體,那麼那1.9gb就沒有實際用處了,這就太浪費資源了。而實際上這個64tb也沒有什麼實際意義,因為32位的位址匯流排能定址的線性位址空間和實體地址空間都是2^32=4gb。這個64tb是怎麼出來的,稍後揭曉。
我們先來說一下為什麼有實模式和保護模式的區別。最早期的8086 cpu只有一種工作方式,那就是實模式,而且資料匯流排為 16位,位址匯流排為20位,實模式下所有暫存器都是16位。而從80286開始就有了保護模式,從80386開始cpu資料匯流排和位址匯流排均為32位,而且暫存器都是32位。但80386以及現在的奔騰、酷睿等等cpu為了向前相容都保留了實模式,現代作業系統在剛加電時首先執行在實模式下,然後再切換到保護模式下執行。
邏輯位址:即邏輯上的位址,實模式下由「段基位址+段內偏移」組成;保護模式下由「段選擇符+段內偏移」組成。
線性位址:邏輯位址經分段機制後就成線性位址,它是平坦的;如果不啟用分頁,那麼此線性位址即實體地址。
實體地址
剛才說了8086cpu資料匯流排為16位,也就是一次最多能取2^16=64kb資料,這個資料也解釋了實模式下為什麼每個段最大只有64kb。但剛才還說了其位址匯流排為20位,這樣它能定址的能力其實是2^20=1mb,這也就是實模式下cpu的最大定址能力。既然它有1mb定址能力,那怎麼用16位的段暫存器表示呢?
這就引出了分段的概念,8086cpu將1mb儲存空間分成許多邏輯段,每個段最大限長為64kb(但不一定就是64kb)。這樣每個儲存單元就可以用「段基位址+段內偏移位址」表示。段基位址由16位段暫存器值左移4位表達,段內偏移表示相對於某個段起始位置的偏移量。比如:
seg=0x07c0
jmpi offset, #seg
offset: mov ax,cs
在定義「邏輯位址」時看到保護模式和實模式的區別在於它是用段選擇符而非段基位址,這也許就是保護模式的真諦所在,從段選擇符入手,全面理解保護模式程式設計基本概念和定址方式。
下面來看下保護模式是怎樣通過「段選擇符+段內偏移」定址最終的線性位址或實體地址的。
圖1 邏輯位址到線性位址轉換,這裡的邏輯位址即指保護模式下的「段選擇符+段內偏移位址」,如果不啟用分頁管理的情況下,那麼此線性位址即最終的實體地址。
圖1 邏輯位址到線性位址轉換
在理解此圖時必須要明白段選擇符結構、描述符表概念等,下面就一一介紹。
如圖2段選擇符結構,段選擇符為
16位,它不直接指向段,而是通過指向的段描述符,段描述符(一會介紹)再定義段的資訊。
圖2 段選擇符結構
其中ti
用來指明全域性描述符表
gdt還是區域性描述符表
ldt,
rpl表示請求特權級,索引值為
13位,所以從這裡看出,在保護模式下最多可以表示
2^13=8192
個段描述符,而
ti又分
gdt和
ldt(如圖
3所示),所以一共可以表示
8192*2=16384
個段描述符,每個段描述符可以指定乙個具體的段資訊,所以一共可以表示
16384
個段。而圖
1看出,段內偏移位址為
32位值,所以乙個段最大可達
4gb,這樣
16384*4gb
=64tb
,這就是所謂的
64tb
最大定址能力,也即邏輯位址
/虛擬位址。
。其中的
8即段選擇符,
8的二進位制表示為:
0000 0000 0000 1000b
,所以這條語句的意思是跳轉到
gdt表(ti=
0)中的第
2個(段描述符表從0開始編號,所以這裡的
1指表中的第
2個)段描述符定義的段中,其段內偏移為0。
下面再來看段描述符結構,段描述符表中的每一項為乙個段描述符,每一項為8
位元組,其結構如圖4
所示。
從圖中可知,段選擇符指向的段描述符裡有三個部分基位址資訊,這三部分組成乙個32
位位址就決定了段基位址位置,此位址再加上段內偏移最終確定線性位址位置。
段描述符中的s
位和type
字段(四位)的不同又分為資料段描述符、**段描述符(
s=1)和系統段描述符
(s=1)
。資料段和**段描述符型別如圖
5所示。
圖5系統段描述符如圖6
所示。
到目前為止我們知道了保護模式下是怎樣通過段選擇符指向乙個段描述符,最終由段描述符+
段內偏移定位線性位址,在不啟用分頁情況下,此線性位址就是實體地址,那麼在啟用分頁情況下,又是怎樣實現記憶體的對映轉換的呢?這就是偉大的分頁機制。
分頁機制如下圖所示,它把物理記憶體分成相同固定大小的頁面,2^12=4kb
。每個頁面的
0~4kb
範圍由線性位址的低
12位表示,線性位址空間的高
10位用來指定頁目錄中的位置,可以選擇
2^10=1024
個目錄項,每個目錄項為四位元組,所以頁目錄為
1024*4b=4kb
。每個目錄項中的高
20位用以查詢頁表在物理記憶體中的頁面,每個頁表含
1024
個頁表項,每個頁表項也是四位元組,這樣一頁表也是
1024*4b=4kb
。所以乙個頁目錄可以查詢
1024
個頁表,每個頁表為
4kb,所以總共可以查詢的頁表大小為
1024*4kb
=4mb
大。最後每個頁表項的高
20位用以定位實體地址空間中的某個頁基位址,此位址再加上線性位址空間的偏移值就是最後物理記憶體空間單元。目錄項和頁表項結構如圖
8所示。
圖7分頁機制
從乙個邏輯位址經過分段和分頁定址實體地址的整個過程就如圖9
所示。總的來說整個過就是邏輯位址經分段機制變成線性位址,如果不啟用分頁的情況下,此線性位址就是實體地址;如果啟用分頁,那麼線性位址經分頁機制變成實體地址。
圖9分段和分頁
說了半天分段和分頁的原理,它們到底有何用?這裡以保護模式下分段和分頁講解。
圖10
多段模型
如圖10
所示。乙個多段模型充分發揮了段機制的對**、資料結構和程式提供硬體保護的能力。每個程式都有自己的段描述符表和自己的段。段可以完全屬於程式私有也可以和其它程式之間共享。
訪問許可權的檢查不僅僅用來保護位址越界,也可以保護某一特定段不允許操作。例如**段是唯讀段,硬體可以阻擊向**段進行寫操作。
分頁為需求頁、虛擬記憶體提供實現機制。具體的實現機制可以再深入學習。
《深入理解linux
核心》
《linux
核心完全剖析》趙炯
《linux
核心設計與實現》
《linux
核心修煉之道》
《新版組合語言程式設計》錢曉捷著
《windows
環境下32
位組合語言程式設計》羅雲彬著
實模式和保護模式區別及定址方式
實模式和保護模式區別及定址方式 我記得大學的彙編課程,組成原理課裡老師講過實模式和保護模式的區別,在很多書本上也有談及,無奈本人理解和感悟能力實在太差,在很長一段時間裡都沒真正的明白它們的內含,更別說為什麼實模式下最大定址空間為1mb?段的最大長度不超過64kb?而保護模式下為啥最大定址能力就變成了...
實模式和保護模式區別及定址方式
實模式和保護模式區別及定址方式 出處 我記得大學的彙編課程 組成原理課裡老師講過實模式和保護模式的區別,在很多書本上也有談及,無奈本人理解和感悟能力實在太差,在很長一段時間裡都沒真正的明白它們的內含,更別說為什麼實模式下最大定址空間為1mb?段的最大長度不超過64kb?而保護模式下為啥最大定址能力就...
實模式和保護模式區別及定址方式
我記得大學的彙編課程 組成原理課裡老師講過實模式和保護模式的區別,在很多書本上也有談及,無奈本人理解和感悟能力實在太差,在很長一段時間裡都沒真正的明白它們的內含,更別說為什麼實模式下最大定址空間為1mb?段的最大長度不超過64kb?而保護模式下為啥最大定址能力就變成了64tb?每個段最大也達4gb?...