32位的虚拟地址翻释成32位的物理地址

来源:互联网 发布:绝对萌域淘宝 编辑:程序博客网 时间:2024/05/22 06:26

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
   ...

 

原创粉丝点击