日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

x86分页机制详解

發(fā)布時間:2025/3/15 编程问答 7 豆豆
生活随笔 收集整理的這篇文章主要介紹了 x86分页机制详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 1. 為什么會有分頁機制?
  • 2. 從虛擬地址到物理地址
  • 3. 簡單的分頁模型
  • 4. 頁表和頁目錄
    • 4.1 層次化的分頁結(jié)構(gòu)
    • 4.2 頁表
    • 4.3 頁目錄
  • 5. 地址變換的具體過程

1. 為什么會有分頁機制?

有些資料說是為了實現(xiàn)“虛擬內(nèi)存”,真的是這樣嗎?如果沒有分頁機制,能否實現(xiàn)“虛擬內(nèi)存”?答案是肯定的。

當同時運行的任務很多時,內(nèi)存可能就不夠用。

如圖所示,每個段描述符都有 AVL 位(簡稱 A 位),用于表示一個段最近是否被訪問過(準確地說是表明從上次操作系統(tǒng)清零該位后一個段是否被訪問過)。

當創(chuàng)建描述符的時候,應該把 A 位清零。之后,每當該段被訪問時,準確地說是處理器把這個段的段選擇符加載進段寄存器時,CPU 就將該位置“1”;對該位的清零是由操作系統(tǒng)負責的,通過定期監(jiān)視該位的狀態(tài),就可以統(tǒng)計出該段的使用頻率(比如,每 1 秒鐘查看一次,一旦置位就清零,統(tǒng)計 10 秒鐘內(nèi)被置位了多少次,次數(shù)越多說明使用越頻繁)。當內(nèi)存空間緊張時,可以把不經(jīng)常使用的段退避到硬盤上,從而實現(xiàn)虛擬內(nèi)存管理。

當某個段被換出到磁盤時,操作系統(tǒng)應該將這個段的描述符的 P 位清零。過上一段時間,當再次訪問這個段時,因為它的描述符的 P 位是 0,處理器就會引發(fā)段不存在異常(中斷號 11)。這類中斷通常是由操作系統(tǒng)處理的,它會用同樣的方法騰出空間,然后把這個段從磁盤調(diào)入內(nèi)存。當這類中斷返回時,處理器會再次執(zhí)行引發(fā)異常的那條指令,這時候段已經(jīng)在內(nèi)存中(P=1),于是程序又可以繼續(xù)執(zhí)行了。

由此可見,即使沒有分頁機制,利用“分段”也可以實現(xiàn)“虛擬內(nèi)存”。

但是,因為段的長度不固定,在段的換入換出時會產(chǎn)生外部碎片,這樣就浪費了很多內(nèi)存。為了解決這個問題,從 80386 處理器開始,引入了分頁機制。分頁機制簡單來說,是用長度固定的頁來代替長度不定的段,以解決因段的長度不同帶來的內(nèi)存空間管理變得復雜的問題。

盡管操作系統(tǒng)也可以利用純軟件來實施固定長度的內(nèi)存分配,但是過于復雜。由處理器固件來做這件事情,可以省去很多麻煩,速度也可以提高。

總結(jié)一下,引入分頁機制并不是為了實現(xiàn)虛擬內(nèi)存,而是為了解決內(nèi)存碎片的問題。

2. 從虛擬地址到物理地址

分頁機制是 80x86 內(nèi)存管理機制的第二部分。分段機制把邏輯地址轉(zhuǎn)換成線性地址,而分頁機制則把線性地址轉(zhuǎn)換成物理地址。

分頁機制會把線性地址空間(段已映射到其中)劃分成頁面,然后這些線性地址空間的頁面被映射到物理地址空間的頁面上。如下圖所示:


80x86 使用 4K(2 的 12 次方)字節(jié)固定大小的頁面。每個頁面均是 4KB,且對齊于 4K 地址邊界處(地址的低 12 位全是 0)。

3. 簡單的分頁模型

4GB(2 的 32 次方)的線性地址空間可以劃分為 1048576(= 2 的 20 次方,即 1M)個頁面。為了根據(jù)線性地址找到對應的物理地址,操作系統(tǒng)必須維護一張表(如下圖所示)。


這個表暫且叫做“頁映射表”,它一共有 1048576 個表項,每個表項占 4 個字節(jié),其內(nèi)容是某個頁的起始物理地址(共 32 比特,低 12 位全為 0)。

頁映射表是這樣使用的:因為頁的尺寸是 4KB,所以線性地址的低 12 位可以作為頁內(nèi)偏移,高 20 位可以用來索引一個表項,找到了這個表項,就找到了對應的物理頁。

具體可以參考我的博文:簡單的分頁模型

4. 頁表和頁目錄

4.1 層次化的分頁結(jié)構(gòu)

上文提到的頁映射表,一共有 1048576(=1M)個表項,每個表項占 4 個字節(jié),所以表的大小是 4MB,在當時看來要占用相當一部分內(nèi)存。考慮到在實踐中,沒有哪個任務會真的用到所有表項,充其量只是很小一部分,所以內(nèi)存中放一個 4MB 的表格確實很浪費。也許你會建議,能不能先劃出一小片內(nèi)存,只存表格用到的部分,然后根據(jù)需要動態(tài)擴展。的確,這個方法可行。但是因為特殊原因(任務的 4GB 地址空間包括兩個部分:局部空間和全局空間。頁目錄的前半部分指向任務自己的頁表,后半部分則指向內(nèi)核的頁表。整個映射表的前一半對應全局地址空間,后一半對應局部地址空間),這張表從一開始就必須完全定義,所以不可避免地要占用 4MB 的內(nèi)存空間。為了解決這個問題,同時又不會浪費寶貴的內(nèi)存空間,處理器設(shè)計了層次化的分頁結(jié)構(gòu)。

4.2 頁表

4GB 的線性地址空間可以劃分為 1048576(2 的 20 次方,即 1M,也可以看成是 1024*1024)個頁面,所以,可以隨機地抽取這些頁面,每 1024 個頁面是一組,可以分成 1024 組。對于每組中 1024 個頁面的物理地址,按某種順序排列可以構(gòu)成一張表(每個表項都是一個頁面的物理地址),這個表就是頁表。頁表的大小是 1024*4B=4KB,剛好是一個物理頁的大小。

4.3 頁目錄

因為已經(jīng)分成了 1024 組,每組都有一個頁表(大小為 4KB),所以這 1024 個頁表又可以用一張表來指向,這就是頁目錄。類似于頁表,頁目錄共有 1024 個表項(稱作頁目錄項),**每個頁目錄項的內(nèi)容是某個頁表的物理地址。**頁表的大小是 1024*4B=4KB,剛好是一個物理頁的大小。

有人說,這樣不是更占內(nèi)存嗎?原來需要 4MB,現(xiàn)在存放 1024 個頁表就要 4MB,再加上一個頁目錄,還要 4KB,何苦呢?

  • 這樣的層次化分頁結(jié)構(gòu)是每個任務都有的,或者說每個任務都有自己的頁目錄。在處理器內(nèi)部,有一個控制寄存器叫 CR3,存放著當前任務的頁目錄的物理地址,故 CR3 又叫做頁目錄基址寄存器(Page Directory Base Register,PDBR).

  • 每個任務都有自己的 TSS(Task-State Segment ,任務狀態(tài)段),其中就包括了 CR3 寄存器域,存放著任務自己的頁目錄的物理地址。當任務切換時,CR3 寄存器的內(nèi)容也會被更新,更新為新任務的頁目錄的物理地址。

  • 頁目錄和頁表也是普通的頁,混跡于全部的物理頁中。它們和普通的頁沒有什么區(qū)別,無非就是功能不一樣。當任務被操作系統(tǒng)撤銷后,它們和任務所占用的普通的物理頁一樣會被回收。

  • 頁目錄總是在物理內(nèi)存中,頁表可以在需要時再分配,這樣就大大節(jié)省了物理內(nèi)存。這就回答了前面的問題。

  • 5. 地址變換的具體過程

    具體怎么變換,還是用書上的例子來說明吧。
    假設(shè)段部件輸出的線性地址是 0x00801050,如果沒有開啟分頁,那么這個地址就是物理地址;但是現(xiàn)在開啟了分頁,所以要經(jīng)過頁部件的轉(zhuǎn)換,才能得到物理地址。

    處理器的頁部件專門負責線性地址到物理地址的轉(zhuǎn)換工作。它首先將 32 位的線性地址分成 3 段,分別是高 10 位,中間 10 位和低 12 位。高 10 位用來索引頁目錄,中間 10 位用來索引頁表,低 12 位作為頁內(nèi)偏移。

  • 當前任務的頁目錄的物理地址在 CR3 寄存器中,假設(shè)是 0x0000_5000;
  • 段部件輸出的線性地址是 0x0080_1050,按照高 10 位,中間 10 位和低 12 位分為三段,分別是0x002,0x001,0x050;
  • 0x002 乘以 4(因為每個表項占 4 個字節(jié))得到 0x008,作為偏移訪問頁目錄,得到了0x0800_1000,這就是頁表的物理地址,順著它找到頁表;
  • 0x001 乘以 4(因為每個表項占 4 個字節(jié))得到 0x004,作為偏移訪問頁表,得到了0x0000_c000,這就是我們要找的那個物理頁的起始地址。
  • 0x050 作為頁內(nèi)偏移,和物理頁的起始地址 0x0000_c000相加,得到 0x0000_c050,這就是最終的物理地址。

  • 參考資料
    【1】《x86匯編語言:從實模式到保護模式》(李忠,電子工業(yè)出版社)
    【2】《Linux內(nèi)核完全剖析》(趙炯,機械工業(yè)出版社,2006)

    總結(jié)

    以上是生活随笔為你收集整理的x86分页机制详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。