記憶體定址的三種模型
1. 地址的種類
首先明確一下邏輯地址和線性地址這兩個概念:
1. 邏輯地址
2. 線性地址
3. 實體地址
1.1 邏輯地址:
邏輯地址是編譯器生成的,我們使用在linux環境下,使用C語言指標時,指標的值就是邏輯地址。對於每個程序而言,他們都有一樣的程序地址空間,類似的邏輯地址,甚至很可能相同。
1.2 線性地址:
線性地址是由分段機制將邏輯地址轉化而來的,如果沒有分段機制作用,那麼程式的邏輯地址就是線性地址了。
1.3 實體地址
實體地址是CPU在地址總線上發出的電平訊號,要得到實體地址,必須要將邏輯地址經過分段,分頁等機制轉化而來。
2. 三種定址模型
x86體系結構下,使用的較多的記憶體定址模型主要有三種:
1. 真實模式扁平模型 real mode flat model
2. 真實模式分段模型 real mode segment model
3. 保護模式扁平模型 protected mode flat model
下面是對這三種模型的描述
真實模式和保護模式相對,真實模式運行於20位地址匯流排,保護模式則啟用了32位地址匯流排,地址使用的是虛擬地址,引入了描述符表;雖然二者都引入了段這樣一個概念,但是真實模式的段是64KB固定大小,只有16KB個不同的段,CS,DS等儲存的是段的序號(想想為什麼?)。保護模式則引入了GDT和LDT段描述符表的資料結構來定義每個段。
扁平模型和分段模型相對,區別在於程式的線性地址是共享一個地址空間還是需要分成多個段,即為多個程式同時執行在同一個CS,DS的範圍內還是每個程式都擁有自己的CS,DS:前者(flat)指令的邏輯地址要形成線性地址,不需要切換CS,DS;後者的邏輯地址,必須要經過段選擇子去查詢段描述符,切換CS,DS,才能形成線性地址。
3. 真實模式扁平模型
該模式只有在386及更高的處理器中才能出現!
80386的真實模式,就是指CPU可用的地址線只有20位,能定址0~1MB的地址空間。注意:80386的真實模式並不等同於8086/8088的真實模式,後者的真實模式其實就是真實模式分段模型!
扁平模型,意味著我們這裡不使用任何的分段暫存器。(其實還是使用了CS,DS,只是不用程式設計師去顯示地為該暫存器賦值,jmp指令時就已經將CS, DS設定好了)
Linux啟動程式碼 arch/i386/boot/bootsect.S就工作在該模式下。
4. 真實模式分段模型
對於 8086/8088 執行在真實模式的程式,其實就是執行在真實模式分段模型中。對於不同的程式,有不同的CS,DS值,每個程式的段起始地址都不同。對於這樣的程式而言,偏移地址16位的特性決定了每個段只有64KB大小。
5. 保護模式扁平模型
我們的Linux, Window XP/7採用的記憶體定址模型,Linux中,段主要分為4種,即為核心程式碼段,核心資料段,使用者程式碼段,使用者資料段。
對於核心程式碼段和資料段而言,CS,DS的值是0xC00000000,而使用者程式碼和資料段的CS,DS的值是0x00000000
當CPU運行於32位模式時,不管怎樣,暫存器和指令都可以定址整個線性地址空間,所以根本就不需要再去使用基地址。基址可以設為一個統一的值。
扁平模型在這裡得到了很好的體現,這個使用者空間的程式基地址是0,。事實上,所有的使用者空間的程式,其GDT指向的基地址都是0。