32位的虛擬地址翻釋成32位的物理地址

32位的虛擬地址翻釋成32位的物理地址

    自 386開始,IA-32處理器開始支持分頁機制。分頁機制的主要目的是高效地利用內存,按頁來組織和管理內存空間,把暫時不用的數據放到外部存儲器(通常 是硬盤)上。在啓用分頁機制後,操作系統將將線性地址空間劃分爲固定大小的頁面(4kb、2MB、4MB)。每個頁面可以被映射到物理內存或外部存儲器上 的虛擬內存文件中。 下面就介紹一下WINDOWS是如何把32位的虛擬地址翻釋成32位的物理地址的。

    我們先看下面的一張圖:


    

    我們可以用通常書本中的目錄來理解。請看十圖:

    

    一、在進入主題之前,我們來理解三個概念:CR3寄存器、頁目錄、頁表。

    1、CR3寄存器。
    CR3寄存器又稱爲頁目錄基址寄存器。

    2、頁目錄。
    頁目錄是存放頁目錄表項(Page-Directory Entry, 簡稱PDE)線性表。每個頁目錄佔一個4KB的內存頁,每個PDE的長度爲32個比特位(4字節),因此每個頁目錄中最多包含1024個PDE。下圖畫出 了指向4KB頁表的PDE的大概的格式,圖中高20位代表該PDE所指向頁表起始物理地址的高20位,該起始物理地址的低12位固定爲零,所以頁表一定是 按照4KB對齊的。

    

指向頁表的頁目錄表項(PDE)的格式

    3、頁表。
    頁表是用來存放頁表表項(Page-Table Entry, 簡稱PTE)的線性表。每個表佔一個4KB的內存頁,每個PTE的長度爲32比特位,因此每個頁表中最多包含1024個PTE。下圖畫出了PTE的大概的 格式,其中高20位代表的是4KB內存頁的起始物理地址的的高20位,該起始物理地址的低20位假定爲零,所以4KB內存頁都是按4KB進行對齊的。

     

頁表表頁(PTE)的格式

   二、地址翻譯。

   有了上面的基礎後,下面就來看一下CPU是如何利用頁目錄和頁表等數據結構將一個32位的虛擬地址翻譯爲32位的物理地址的。其過程可以概括如下:

   1、通過CR3寄存器定位到頁目錄的起始地址,正因爲如此,CR3寄存器又被稱爲頁目錄基地址寄存器。
   2、取線性地址的高10位作爲索引選取頁目錄的一個表項,也就是PDE。
   3、根據PDE中的頁表基地址(取PDE的高20位,低12位設爲零)定位到頁表。
   4、取線性地址的12位到21位(共10位)作爲索引選取頁表的一個表頁,也就是PTE。
   5、取出PTE中的內存基地址(取PTE的高20位,低12位設爲零)。
   6、取線性地址的低12位作爲頁中的偏移與上一步的內存頁基地址相加便得到物理地址。

   這整個過程就是本頁的第一個圖所描繪的。

   三、下面通過實例來說明。

   這個實驗要求在安裝好了WinDBG工具Windows XP SP1的進行。
   1、運行計算器程序(calc.exe),鍵入一串數字(如123456789)以便後面的觀察。
   2、啓動WinDBG,並附加到計算器程序上開始調試(File|Attach to process...)。
   3、在WinDBG的命令區中輸入x calc!g*命令列出所有以g開頭的符號。注意其中包含的gpszNum行。

   01014db0 calc!gqszNum = <no type information>

   3、在WinDBG命令區輸入dd calc! gpszNum 11命令,查看該符號地址的內容.

   01014db0 000a6c88

   5、繼續查看地址000a6c88(應該換作你試驗時看到的值)處的內容:dd 000a6c88

   0:002>dd 000a6c88
   000a6c88 00320031 00340033 00360035 00380037
   000a6c98 00000039 00000000 00040004 000c0100
   ...

   6.看來000a6c88指向的很像我們前面輸入的數字。使用顯示字符串命令進一步驗證:

   0:002> du 000a6c88
   000a6c88 “123456789”

      看來真是如此,嘗試鍵入其他的數字,再重複第4到第6步,可以進一步驗證。主意gpszNum11的值是會變化的,也就是它是指向一個動態分配的緩衝 區,該緩衝區包含了用戶輸入的字符串。下面我們來看一下如何把這個字符串地址(000a6c88)翻譯爲物理地址。

   7.先將這個虛擬地址轉換爲二進制格式,以便了解它的各個位域的值。這可以使用.formats命令。

   0:002> .formats 000a6c88
   Evaluate expression:
   Hex:     000a6c88
   Decimal:683144
   Octal: 00002466210
   Binary:   00000000 00001010 01101100 10001000

   根據上面的數據,虛擬地址000a6c88的頁目錄索引爲0,頁表索引爲001010110b,即0xA6,頁內偏移爲110010001000b,即0xc88。

   8.再啓動一個WinDBG實例,並開始本地內核調試以便觀察計算器進程的頁目錄基地址。以下所有操作都是在這個WinDBG中進行的。

   9.先通過!process 0 0命令列出所有進程,並在其中找到關於calc.exe的內容。

   lkd> !process 0 0
   **** NT ACTIVE PROCESS DUMP ****
   ...
   PROCESS 86474030 SessionId: 0 Cid: 0bf8   Peb: 7ffdf000 ParentCid: 0d98
        DirBase: 3a744000 ObjectTable: e25acb08 HandleCount: 39.
        Image: calc.exe
   ...

   10.上面的DirBase項描述的就是calc進程的頁目錄基地址的物理地址(CR3寄存器的內容)。也就是說,該進程的內存頁目錄表的基地址是0x3a744000。

   11.使用!dd命令顯示目錄表的內容。

   lk> !dd 3a744000
   #3a744000 15f93067 1b4c8067 0c8ec067 1b1e7067
   #3a744010 2c792067 00000000 00000000 00000000
   #3a744020 00000000 00000000 00000000 00000000
   ...

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章