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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

简单的分页模型

發布時間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单的分页模型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

分頁機制是 80x86 內存管理機制的第二部分。它在分段機制的基礎上完成虛擬(邏輯)地址到物理地址的轉換。為了理解分頁機制,本文介紹一個簡單的分頁模型,雖然簡單,但是對理解真正的分頁模型非常有幫助。咱們開始吧!

在單純的分段模式下,線性地址就是物理地址。

比如下面的匯編語句:

mov edx [0x1008]

這是要把內存中某個位置的值賦給 EDX,但究竟是內存的哪個位置呢?這就要看數據段描述符了。

假設描述符中的段基地址為 0x0020_0000,界限值為 0x2007,段的粒度是字節 ,那么該段的最大長度就是 0x2008(=8200)。

當訪問內存的時候,用段基地址加上段內偏移 0x1008,形成線性地址 0x0020_1008,在沒有開啟分頁的情況下,這就是物理地址。

一旦采用分頁式內存管理,就應該把物理內存分成大小相同的頁。注意,頁在物理內存中的位置是有講究的,并不是在內存中隨便找個位置,說:“來 ,頁從這里開始!”

事實上,頁的單位一般是 4KB,即 4096 (=0x1000)字節。而且,頁的起始地址和 4KB 對齊,所以,第 1 個頁的物理地址是 0x0000_0000,第 2 個頁的物理地址是 0x0000_1000,第 3 個頁的物理地址是0x0000_2000,最后一個頁的物理地址是 0xFFFFF000。

這樣,可以將 4GB 的物理內存劃分為 1048576 (0x 100000) 個頁。很顯然,頁的物理地址,其低 12 位始終為全零。

問題在于,如何將長度不一的段 ,映射到大小相同的頁面上呢?

內存的分配涉及段空間的分配和頁的分配。如下圖所示,左邊是虛擬的 4GB 的內存空間,稱為虛擬內存;右邊呢,是實實在在的物理內存,如果大小是 4GB,就被分成 1048576 個 4KB 頁面;當然,也許只有 2 GB,那就只能劃分成 524288 個 4KB 頁面。

當一個程序加載時,操作系統既在要左邊的虛擬內存屮分配段空間,又要在右邊的物理內存中分配相應的頁面。因此,第一個步驟是尋找空閑的段空間,該段空間既沒有被其他程序使用,也沒有被同一程序內的其他段使用。假設己經成功找到并分配了一個段空間,基地址為 0x00200000,長度為 8200 字節。

頁的最小尺寸是 4KB ,也就是 4096 字節。因此,8200 字節的段,需要占用 3 個頁面,其中最后一個頁面只用了 8 個字節。

作為一個具體的例子,操作系統為程序分配了一個段,段是在虛擬內存中分配的,起始地址為 0x00200000。該段有 8200字節,需要分配 3 個頁面。為此,操作系統在物理內存中搜索可用的
空閑頁,還真找到了,這三個頁面的物理地址分別是:

0x0000_0000 起始的頁面,對應虛擬內存地址 0x0020_0000-0x0020_0FFF

0x0000_1000 起始的頁面,對應虛擬內存地址 0x0020_1000-0x0020_1FFF

0x0000_3000 起始的頁面,對應虛擬內存地址 0x0020_2000-0x0020_2007

這里只是示例,線性地址區間和頁的對應關系可以隨意。

虛擬內存空間不可能用來保存任何數據,因為它是虛擬的。當操作系統加載一個程序并創建為任務時,操作系統在虛擬內存空間尋找空閑的段,并映射到空閑的頁。然后,到真正幵始加載程序時,再把原本屬于段的數據按頁的尺寸拆開,分別寫入對應的頁中。

從段部件輸出的是線性地址,為了根據線性地址找到頁的物理地址,操作系統必須維護一張轉換表,把線性地址轉換成物理地址。

因為虛擬的 4GB 內存可以分成 1048576 個頁,所以轉換表也有 1048576 項 。每個表項占 4 字節,內容為頁的物理地址。這個表格的用法是這樣的:因為頁的尺寸是 4K B , 故,線性地址的低 12 位可用于訪問頁內偏移,高 20 位可用于指定一個物理頁。因此,把線性地址的高 20 位當成索引,乘以 4 ,作為表內偏移量,從表中取出一個雙字(4B),就是該線性地址所對應的頁的物理地址。


例如,執行指令
mov edx, [0x2002]

首先,要算出線性地址,用段地址 0x0020_0000 加上 0x2002,得到線性地址 0x0020_2002;然后把線性地址轉換為物理地址:線性地址的高 20 位是轉換表的索引,即 0x202(=514),即表格的第 514 項。如果按照字節索引,需要把 0x202 乘以 4,得到 0x808,看圖,從該單元可以取出一個雙字 0x0000_3000,這就是頁的起始物理地址。線性地址的低 12 位是頁內偏移量,用頁物理地址加上頁內偏移量,就是最終的物理地址。0x0000_3000 加上 0x002,得到 0x0000_3002,所以物理地址就是 0x0000_3002。

有人問,表格里面的 0x0000_3000 是怎么來的?

當程序加載時,操作系統首先在虛擬內存中分配段。然后,根據段需要分成多少頁,來搜索空閑頁面。當段較大時,要按頁的尺寸分成好幾個地址區段,操作系統用每個區段的首地址,取高 20 位 ,乘以 4 ,作為偏移最訪問表格,并將分配給該區段的頁的物理地址寫入該表項。最后,把原本需要寫入每個區段的程序數據,寫到對應的頁中。

注意了,在頁式內存管理中,頁面的管理和分配是獨立的,和分段以及段地址沒有關系。操作系統所要做的,就是尋找空閑頁面,把它分配給需要的段,并將頁的物理地址填寫到映射表內。

一般來說,每個任務都可以擁有 4GB 的虛擬內存空間;同時,每個任務都有自己的頁映射表,如圖 16-5 所示。

每個任務都有自己的 4GB 虛擬內存空間,這個怎么理解呢?

考慮這樣一種情景 :任務 A 有一個段 , 段基地址為 0x0005_0000,段長度為 3000 字節,操作系統為它分配了一個物理地址為 0x0800_1000 的頁。過了一會兒,另一個任務 B 加載了,它也有一個段,段基地址也為 0x0005_0000,段長度 4000 字節,此時,操作系統則分配另一個不同的、物理地址為 0x0070_0000 的頁。

在這種情況下,任務 A 訪問線性地址 0x0005_0006,訪問的其實是物理地址 0x0800_1006;在任務 B 內訪問同樣的線性地址 0x0005_0006,訪問的其實是物理地址 0x0070_0006。

你看,線性地址都是一樣的,但是被映射到了不同的物理地址上。

另一個會被質疑的問題是,每個任務都有 4GB 虛擬內存空間,而物理內存只有一個,最大也才 4GB , 根本不夠分啊。事實上,的確不夠分。但是,操作系統可以將暫時不用的頁退避到磁盤,調入馬上就要使用的頁,通過這種手段來實現分頁內存管理。

以上就是一個簡單的分頁模型,如果理解了,就會為后面學習兩級頁表結構打下基礎。


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

總結

以上是生活随笔為你收集整理的简单的分页模型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。