CPU記憶體管理員模式與 定址

來源:互聯網
上載者:User

 

 

 

32位cpu 地址匯流排擴充成了32位,這和資料匯流排的寬度是一致的。因此,在32位機裡其實並不需要採用“物理地址=段:位移”這種地址表達方式。原來在16位機裡規定的每一個段不大於64kb在32位機裡也不是必要的。所以,對於32位機來講,最簡單的方法就是用一個32位元來標識一個位元組的儲存地址,定址時只要給出一個32位元就可以直接找到地址。這種地址儲存模型就屬於“平展儲存模型”。

但是,新產品一般都希望遵循“向下相容”這個原則。所以,32位機裡完整的保留了16位定址模式。即:定址能力為1M;分段機制;每段不超過64kb。這就是通常所說的"實模式"。在地址儲存模型中屬於“真實位址儲存模型”。

   其次,考慮到程式通常都是功能化的模組,所以分段雖然不是必要的,但分段卻能大大提高編程者管理程式的效率。故而32位機也採用了段+位移的模式來定址。但與實模型不同的是,由於地址線和資料線寬度一致,因而,每個段最大可以到4G,並且段基址也是32位的無需進行左移處理。在地址儲存模型中這屬於“段地址儲存模型”。然而需要注意的是,在32位機裡,雖然通用寄存器,標誌寄存器等都擴充成了32位,但是段寄存器卻依然是16位的(為什麼不做改變??我猜可能是這樣便於向下相容)。所以在32位定址時,段寄存器裡放的不再是段基址(位元不夠,放不下)而是一個選擇子。這個選擇子對應了一個64-bit長的描述符,64-bit的描述符裡有32-bit是段基址。所以原來在16位機裡通過段寄存器一步就可以找到段基址,而現在在32位機裡分成了兩步:先找選擇子,然後通過選擇子找段基址。段基址找到了,再加上位移地址,物理地址就找到了。看樣子,32位段模式定址已經介紹清楚了。其實,這裡頭的故事還遠沒有講完。

    在上面簡述的過程中,很容易發現有兩個問題沒有交待。(1)CPU是如何將選擇子與描述符對應起來的?(2)既然是64-bit的描述符,32位用來表示基地址,那麼餘下的32位是幹什麼用的?另外,當32位機發展起來的同時,作業系統也有了長足進步,單任務模式的DOS被多任務的windows所取代。也就是說,現在駐留在記憶體中的往往不止是一個程式,而很可能是多個程式同時在記憶體中。現在又沒有了段大小的限制,程式之間便很有可能相互搶地址,如果核心程式被破壞,電腦就會崩潰。這就好比在馬路上走車,如果只有一輛車開,怎麼開都可以,但是如果車多了不制定個交通規則,車便會搶道,道路就會癱瘓。所以,在多任務的情況下,必須給定址也制定一個“交通規則”,這樣才能保證多任務系統有序的工作。制定什麼樣的規則呢?首先,既然程式是在無意識的情況下搶佔了別的程式的地址,那麼如果在定址時包含一個查詢的過程就可以有效避免搶地址的情況發生。也就是說,先得問一問那個地址是不是已經有程式段佔用了?同時已佔上地址的程式段除了告知CPU自己的基地址外還應該告訴CPU自己的長度資訊。這樣別的程式段才能方便地查詢。第二,多任務定址最好應該包含優先順序別的內容,已備緊急情況下為核心程式讓道。這好比在馬路上,一般情況下車是遵守規則的,但如果是警車或救護車執行任務時,就可以優先搶佔別的車的道。所以,還應該定義一個優先順序。然後,由占上地址的程式段告訴CPU自己的優先順序別。總的來講,原來在16位機裡很單純的一個“段”的概念現在變得複雜了。如同人的成長過程,剛開始的時候思維總是很幼稚的,相應的也只能解決簡單的問題,只有當你的思維擺脫幼稚的時候,才有能力解決更為複雜的事情。現在CPU擺脫了幼稚的16位,它在描述“段”的時候當然不應該像16位時那麼膚淺。在32位機裡,“段”有三個要素:基地址,長度,屬性(屬性裡包含了優先順序和其它的一些內容)。為了能一次完整的引用或者給出這三個要素,需要新定義一個資料結構。這個結構就是前面所提到的描述符,每一個描述符都佔有64-bit,有足夠的長度來包含段的三個要素。當然,現在記憶體中不止一個程式,而且程式也不止一個段,所以描述符也不會有一個,而是很多個。最簡單的管理方法,就是將所有的描述符集中起來放在一塊連續的儲存空間裡,然後給各個描述符排上序號。當要找某一個特定的描述符時,只要先找到這塊連續的儲存空間然後給出序號就可以了。這些集中起來的描述符形成了一張表,所以通常被叫做描述符表。所以,想找到一個段的資訊,首先要找到描述符表。也就是說,找特定的描述符先要知道描述符表的基地址。在32位cpu中,有一個48位的專用寄存器用來存放通用描述元表的資訊,這個寄存器叫做GDTR。其中,高32位給出了通用描述元表的基地址,低16位給出了描述符表的長度限制。所以,一張通用描述元表最長可以是64kb。那麼,最多可以放64kb/8b=8k個描述符。所以如果想在其中選擇任意一個描述符,用13位就可以辦到了。在32位cpu中,16位段寄存器的高13位就用來存放特定描述符的序號。其實,現在段寄存器的功能就是選擇描述符,正因為如此,通常也把段寄存器叫做選取器。那麼,經過冗長的介紹,現在32位段定址的過程已經大體依稀浮現在眼前了:在段寄存器裡找到序號,在GDTR中找到通用描述元表的基地址,然後就可以找到目的描述符。再從描述符中取出段的基地址,然後加上位移地址,這樣就得到了段的“物理地址”。

     真是令人興奮,這樣的定址過程為執行多任務提供了有力的保障,可以想象這是電腦執行效能上的一次飛躍!從此高速的cpu再也不會為無用武之地發愁了,它可以最大限度的發揮自己速度快的優勢,同時處理好多個任務。是的,當我們眼前出現了新的景象的時候,我們有理由興奮。但是,我們不應該就此滿足。我們應該沿著新天地撇給我們的一絲亮光,繼續前行,去找到這片新天地。人就是在這樣的前行中不斷讓事情變得更完美。到這裡,我們對於定址過程的瞭解,只是開了一個頭而已,但這是一個好頭,我們體會到了32位cpu的強大優勢。這足以讓我們對完整的32位CPU定址充滿了期待。讓我們鼓舞士氣,沿著前人的足跡繼續前行吧!

     我們知道,程式碼和資料必須駐留在記憶體中才能得以運行,然而系統記憶體數量很有限,往往不能容納一個完整程式的所有代碼和資料,更何況現在是多任務系統,想讓記憶體駐留所有任務程式顯然不太可能。老式系統就是將程式分割成小份,只讓當前系統運行它所有需要的那部分留在記憶體,其它部分都留在硬碟。當系統處理完當前任務片段後,再從外存中調入下一個待啟動並執行任務片段,而且這個工作是由程式員自行完成。顯然這增加了程式員的負擔。
      由此針對多任務系統發展了一種虛擬記憶體技術。虛擬記憶體技術就是一種由作業系統接管的按需動態記憶體分配的方法,它允許程式不知不覺中使用大於實際物理空間大小的儲存空間(其實是將程式需要的儲存空間以頁的形式分散儲存在實體記憶體和磁碟上)。虛擬記憶體是將系統硬碟空間和系統實際記憶體聯合在一起供進程使用,給進程提供了一個比記憶體大得多的虛擬空間。在程式運行時,把虛擬位址空間的一小部分映射到記憶體,其餘都儲存在硬碟上(也就是說程式虛擬空間就等於實際實體記憶體加部分硬碟空間)。當被訪問的虛擬位址不在記憶體時,則說明該地址未被映射到記憶體,而是被存貯在硬碟中,因此需要的虛擬儲存地址隨即被調入到記憶體;同時當系統記憶體緊張時,也可以把當前不用的虛擬儲存空間換出到硬碟,來騰出實體記憶體空間。       這樣,為了提高系統效能,發展了虛擬記憶體技術,那麼相應的,32位cpu也應該發展新的定址技術來管理虛擬記憶體。這是通過頁機制來實現的。
       因為使用頁機制的原因,前面提到的通過段機制轉換得到的地址僅僅是作為一個中間地址——線性地址了,該地址不代表實際物理地址,而是代表整個進程的虛擬空間地址。還得有一個將虛擬位址轉換成物理地址的過程。

       讓我們來認識一下頁機制。它就是把記憶體分成一個一個連續的頁,每頁大小4kb。與段不同,頁不是程式功能塊的體現。一個程式功能塊可能佔用好多個頁。現在記憶體就像一本書了,一頁一頁的,每頁的容量都是相等的。當然,我們很快可以聯想到,要想能夠很快的找到某頁,最好給這本書分個章或者節什麼的,然後逐級地向下查詢。這就是32位cpu裡頁目錄和頁表所起的作用。頁目錄的長度是4kb,它最多可以包含1024個頁目錄項,每個頁目錄項32-bit,包含了頁表的地址和有關資訊。所以,頁目錄把4Gb空間分成了1024個頁組,每個頁組4MB的大小。頁表的長度也是4kb,1024個頁表項,每個頁表項32-bit,包含頁的地址和其它資訊。這樣,4MB的頁組又被分成了1024個頁面,每個頁面大小4kb。所以找到某一個頁就是先查頁目錄再查頁表這麼一個過程。為了找到頁目錄,我們需要知道其基地址。在32位cpu裡,CR3寄存器裡高20位放的就是頁目錄的地址,因為頁目錄的低12位總是0,這樣保證頁目錄始終是頁對齊的(每頁大小4kB)。再來看一看前面通過32位段機制找到的線性地址。其高10位是頁目錄的位移地址,一共1024個頁目錄用10位就可以標識可能的最大位移了。加上CR3,就可以找到頁目錄,然後再通過頁目錄找到頁表的基地址,線性地址的中間10位放的是頁表的位移量,這樣就找到了頁表。最後頁表的基地址再加上CR3最低12位所表徵的頁表的位移地址就找到了頁,這個頁的地址就是最終的物理地址。

      前面提到,之所以採用頁機制是為了虛擬記憶體技術。所以頁目錄也好,頁表也好,除了地址資訊外還有一些屬性資訊,比如,當前頁表是不是在記憶體中等等。這樣才能方便系統管理虛擬記憶體實施換進換出的功能。這裡就不詳述了。

      總的來講,32位定址先通過32位段機制找到一個32位地址,如果沒有採用分頁,那麼它就是物理地址。否則,只是一個線性地址,然後再通過CR3,頁目錄,頁表找到頁的地址,它才是最終的物理地址。其實,還用很多細節沒有涉及到,比如這裡提到的描述符表是通用描述元表,實際上還有局部描述符表,再比如描述符只重點介紹了地址位,優先順序位和其它屬性位都沒有介紹。但是,一個完整的定址映像已經展現在我們眼前了。它包含了32位CPU裡的所有重要機制。剩下的問題不妨採取暫不過問,現用現學的方法

 

16位cpu分段管理的原因:

16位CPU內部有20根地址線,其編碼區間為:00000H~0FFFFFH,所以,它可直接存取的物理空間為1M(220)位元組。而16位CPU內部存放儲存單元位移量的寄存器(如:IP、SP、BP、SI、DI和BX等)都是16位,它們的編碼範圍僅為:00000H~0FFFFH。這樣,如果用16位寄存器來訪問記憶體的話,則只能訪問記憶體的最低端的64K,其它的記憶體將無法訪問。為了能用16位寄存器來有效地訪問1M的儲存空間,16位CPU採用了記憶體分段的管理員模式,並引用段寄存器的概念。

16位微機把記憶體空間劃分成若干個邏輯段,每個邏輯段的要求如下:

 

圖2.4 16位微機記憶體分段管理

邏輯段的起始地址(通常簡稱為:段地址)必須是16的倍數,即最低4位二進位必須全為0;

邏輯段的最大容量為64K,這由16位寄存器的定址空間所決定。

按上述規定,1M記憶體最多可分成64K個段,即65536個段(段之間相互重疊),至少可分成16個相互不重疊的段。

右圖2.4是記憶體各邏輯段之間的分布情況,其中有相連的段(如:C和D段)、不相連的段(如:A和B段)以及相互重疊的段(如:B和C段)。

這種儲存空間分段的記憶體管理方法不僅實現了用兩個16位寄存器來訪問1M的記憶體空間,而且對程式的重定位、浮動地址的編碼和提高記憶體的利用率等方面都具有重要的實用價值。

 

 

段寄存器的作用:

段寄存器是因為對記憶體的分段管理而設定的。16位CPU有四個段寄存器,所以,其程式可同時訪問四個不同含義的段。段寄存器及其位移量的參考關聯性2.7所示。

段寄存器CS指向存放程式的記憶體段,IP是用來存放下條待執行的指令在該段的位移量,把它們合在一起可在該記憶體段內取到下次要執行的指令。

段寄存器SS指向用於堆棧的記憶體段,SP是用來指向該堆棧的棧頂,把它們合在一起可訪問棧頂單元。另外,當位移量用到了指標寄存器BP,則其預設的段寄存器也是SS,並且用BP可訪問整個堆棧,不僅僅是只訪問棧頂。

段寄存器DS指向資料區段,ES指向附加段,在存取運算元時,二者之一和一個位移量合并就可得到儲存單元的物理地址。該位移量可以是具體數值、符號地址和指標寄存器的值等之一,具體情況將由指令的定址方式來決定。

 

通常,預設的資料區段寄存器是DS,只有一個例外,即:在進行串操作時,其目的地址的段寄存器規定為ES。當然,在一般指令中,我們還可以用強置首碼的方法來改變運算元的段寄存器

 

定址方式:

 

在不使用段超越首碼的情況下,規定:如果有效地址中含有BP,則預設的段寄存器為SS;否則,預設的段寄存器為DS。

 

 

立即定址方式

MOV AH, 80H  

 

運算元作為指令的一部分而直接寫在指令中,這種運算元稱為立即數,這種定址方式也就稱為立即數定址方式。

 ADD AX, 1234H   MOV ECX, 123456H
MOV B1, 12H   MOV W1, 3456H   ADD D1, 32123456H

 

 

寄存器定址方式

 

指令所要的運算元已儲存在某寄存器中,或把目標運算元存入寄存器。把在指令中指出所使用寄存器(即:寄存器的助憶符)的定址方式稱為寄存器定址方式。

1、源運算元是寄存器定址方式

如:ADD VARD, EAX  ADD VARW, AX   MOV VARB, BH等。

其中:VARD、VARW和VARB是雙字,字和位元組類型的記憶體變數。在第4章將會學到如何定義它們。

2、目的運算元是寄存器定址方式

如:ADD BH, 78h    ADD AX, 1234h   MOV EBX, 12345678H等。

3、源和目的運算元都是寄存器定址方式

如:MOV EAX, EBX   MOV AX, BX     MOV DH, BL等。

 

直接定址方式

MOV BX, [1234H],

 

 

 

  

 

 寄存器相對定址方式

 

運算元在儲存空間中,其有效地址是一個基底位址暫存器(BX、BP)或變址寄存器(SI、DI)的內容和指令中的8位/16位位移量之和。其有效地址的計算公式如右式所示。MOV BX, [SI+100H],

基址加變址定址方式

運算元在儲存空間中,其有效地址是一個基底位址暫存器(BX、BP)和一個變址寄存器(SI、DI)的內容之和。其有效地址的計算公式如右式所示。

 MOV BX, [BX+SI],

 

指令所要的運算元已儲存在某寄存器中,或把目標運算元存入寄存器。把在指令中指出所使用寄存器(即:寄存器的助憶符)的定址方式稱為寄存器定址方式。

 

 

 

 相對基址加變址定址方式

運算元在儲存空間中,其有效地址是一個基底位址暫存器(BX、BP)的值、一個變址寄存器(SI、DI)的值和指令中的8位/16位位移量之和。其有效地址的計算公式如右式所示。 MOV AX, [BX+SI+200H],

相對基址加變址定址方式有多種等價的書寫方式,下面的書寫格式都是正確的,並且其定址含義也是一致的。

MOV AX, [BX+SI+1000H]   MOV AX, 1000H[BX+SI]
MOV AX, 1000H[BX][SI]    MOV AX, 1000H[SI][BX]

但書寫格式BX [1000+SI]和SI[1000H+BX]等是錯誤的,即所用寄存器不能在“[“,”]”之外,該限制對寄存器相對定址方式的書寫也同樣起作用。

 

 

 

 

32位cpu的定址方式

 

 

用32位地址位移量進行定址的有效地址計算公式歸納如右式所示。

在32位微機系統中,除了支援前面的七種定址方式外,又提供了一種更靈活、方便,但也更複雜的記憶體定址方式,從而使記憶體位址的定址範圍得到了進一步擴大。

在用16位寄存器來訪問儲存單元時,只能使用基地址寄存器(BX和BP)和變址寄存器(SI和DI)來作為地址位移量的一部分,但在用32位寄存器定址時,不存在上述限制,所有32位寄存器(EAX、EBX、ECX、EDX、ESI、EDI、EBP和ESP)都可以是地址位移量的一個組成部分。

當用32位地址位移量進行定址時,記憶體位址的位移量可分為三部分:一個32位基底位址暫存器,一個可乘1、2、4或8的32位變址寄存器,一個8位/32位的位移常量,並且這三部分還可進行任意組合,省去其中之一或之二。

32位基底位址暫存器是:EAX、EBX、ECX、EDX、ESI、EDI、EBP和ESP;
32位變址寄存器是:EAX、EBX、ECX、EDX、ESI、EDI和EBP(除ESP之外)。

指令所要的運算元存放在記憶體中,在指令中直接給出該運算元的有效地址,這種定址方式為直接定址方式。

在通常情況下,運算元存放在資料區段中,所以,其物理地址將由資料區段寄存器DS和指令中給出的有效地址直接形成,但如果使用段超越首碼,那麼,運算元可存放在其它段

 

 

寄存器間接定址方式

 

 

運算元在儲存空間中,運算元的有效地址用SI、DI、BX和BP等四個寄存器之一來指定,稱這種定址方式為寄存器間接定址方式

 MOV BX,[DI],

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.