老
老人家
Unregistered / Unconfirmed
GUEST, unregistred user!
基本概念<br> Windows 2000 使用基于分页机制的虚拟内存。每个进程有4GB的虚拟地址空间。基于分页机制,这4GB地址空间的一些部分被映射了物理内存,一些部分映射硬盘上的交换文件,一些部分什么也没有映射。程序中使用的都是4GB地址空间中的虚拟地址。而访问物理内存,需要使用物理地址。<br> 下面我们看看什么是物理地址,什么是虚拟地址。<br> 物理地址 (physical address): 放在寻址总线上的地址。放在寻址总线上,如果是读,电路根据这个地址每位的值就将相应地址的物理内存中的数据放到数据总线中传输。如果是写,电路根据这个地址每位的值就将相应地址的物理内存中放入数据总线上的内容。物理内存是以字节(8位)为单位编址的。<br> 虚拟地址 (virtual address): 4G虚拟地址空间中的地址,程序中使用的都是虚拟地址。<br> 如果CPU寄存器中的分页标志位被设置,那么执行内存操作的机器指令时,CPU会自动根据页目录和页表中的信息,把虚拟地址转换成物理地址,完成该指令。比如 mov eax,004227b8h ,这是把地址004227b8h处的值赋给寄存器的汇编代码,004227b8这个地址就是虚拟址。CPU在执行这行代码时,发现寄存器中的分页标志位已经被设定,就自动完成虚拟地址到物理地址的转换,使用物理地址取出值,完成指令。对于Intel CPU 来说,分页标志位是寄存器CR0的第31位,为1表示使用分页,为0表示不使用分页。对于初始化之后的 Win2k 我们观察 CR0,发现第31位为1。表明Win2k是使用分页的。<br> 使用了分页机制之后,4G的地址空间被分成了固定大小的页,每一页或者被映射到物理内存,或者被映射到硬盘上的交换文件中,或者没有映射任何东西。对于一般程序来说,4G的地址空间,只有一小部分映射了物理内存,大片大片的部分是没有映射任何东西。物理内存也被分页,来映射地址空间。对于32bit的Win2k,页的大小是4K字节。CPU用来把虚拟地址转换成物理地址的信息存放在叫做页目录和页表的结构里。<br> 物理内存分页,一个物理页的大小为4K字节,第0个物理页从物理地址 0x00000000 处开始。由于页的大小为4KB,就是0x1000字节,所以第1页从物理地址 0x00001000 处开始。第2页从物理地址 0x00002000 处开始。可以看到由于页的大小是4KB,所以只需要32bit的地址中高20bit来寻址物理页。<br> 页表,一个页表的大小为4K字节,放在一个物理页中。由1024个4字节的页表项组成。页表项的大小为4个字节(32bit),所以一个页表中有1024个页表项。页表中的每一项的内容(每项4个字节,32bit)高20bit用来放一个物理页的物理地址,低12bit放着一些标志。<br> 页目录,一个页目录大小为4K字节,放在一个物理页中。由1024个4字节的页目录项组成。页目录项的大小为4个字节(32bit),所以一个页目录中有1024个页目录项。页目录中的每一项的内容(每项4个字节)高20bit用来放一个页表(页表放在一个物理页中)的物理地址,低12bit放着一些标志。<br> 对于x86系统,页目录的物理地址放在CPU的CR3寄存器中。<br> CPU把虚拟地址转换成物理地址:<br> 一个虚拟地址,大小4个字节(32bit),包含着找到物理地址的信息,分为3个部分:第22位到第31位这10位(最高10位)是页目录中的索引,第12位到第21位这10位是页表中的索引,第0位到第11位这12位(低12位)是页内偏移。对于一个要转换成物理地址的虚拟地址,CPU首先根据CR3中的值,找到页目录所在的物理页。然后根据虚拟地址的第22位到第31位这10位(最高的10bit)的值作为索引,找到相应的页目录项(PDE,page directory entry),页目录项中有这个虚拟地址所对应页表的物理地址。有了页表的物理地址,根据虚拟地址的第12位到第21位这10位的值作为索引,找到该页表中相应的页表项(PTE,page table entry),页表项中就有这个虚拟地址所对应物理页的物理地址。最后用虚拟地址的最低12位,也就是页内偏移,加上这个物理页的物理地址,就得到了该虚拟地址所对应的物理地址。<br> 一个页目录有1024项,虚拟地址最高的10bit刚好可以索引1024项(2的10次方等于1024)。一个页表也有1024项,虚拟地址中间部分的10bit,刚好索引1024项。虚拟地址最低的12bit(2的12次方等于4096),作为页内偏移,刚好可以索引4KB,也就是一个物理页中的每个字节。<br> 一个虚拟地址转换成物理地址的计算过程就是,处理器通过CR3找到当前页目录所在物理页,取虚拟地址的高10bit,然后把这10bit右移2bit(因为每个页目录项4个字节长,右移2bit相当于乘4)得到在该页中的地址,取出该地址处PDE(4个字节),就找到了该虚拟地址对应页表所在物理页,取虚拟地址第12位到第21位这10位,然后把这10bit右移2bit(因为每个页表项4个字节长,右移2bit相当于乘4)得到在该页中的地址,取出该地址处的PTE(4个字节),就找到了该虚拟地址对应物理页的地址,最后加上12bit的页内偏移得到了物理地址。<br> 32bit的一个指针,可以寻址范围0x00000000-0xFFFFFFFF,4GB大小。也就是说一个32bit的指针可以寻址整个4GB地址空间的每一个字节。一个页表项负责4K的地址空间和物理内存的映射,一个页表1024项,也就是负责1024*4k=4M的地址空间的映射。一个页目录项,对应一个页表。一个页目录有1024项,也就对应着1024个页表,每个页表负责4M地址空间的映射。1024个页表负责1024*4M=4G的地址空间映射。一个进程有一个页目录。所以以页为单位,页目录和页表可以保证4G的地址空间中的每页和物理内存的映射。<br> 每个进程都有自己的4G地址空间,从 0x00000000-0xFFFFFFFF 。通过每个进程自己的一套页目录和页表来实现。由于每个进程有自己的页目录和页表,所以每个进程的地址空间映射的物理内存是不一样的。两个进程的同一个虚拟地址处(如果都有物理内存映射)的值一般是不同的,因为他们往往对应不同的物理页。<br> 4G地址空间中低2G,0x00000000-0x7FFFFFFF 是用户地址空间,4G地址空间中高2G,0x80000000-0xFFFFFFFF 是系统地址空间。访问系统地址空间需要程序有ring0的权限。<br> 进程的页目录和页表在虚拟地址空间中的位置<br> 当执行一条访问内存的指令时,如果寄存器中的分页标志位已经被设置,CPU就自动完成虚拟地址到物理地址的转换,来完成该指令。CPU在转换地址过程中,并不需要页目录和页表的虚拟地址。但是分页标志位被设置之后,CPU会把所有指令中的地址当做虚拟地址转换成物理地址。所以程序中使用的都是虚拟地址。一个进程的页表和页目录是由系统维护的,比如一个进程申请或者释放内存,系统就需要设置对应的一些页表项。系统需要访问页目录和页表,但是系统只能使用虚拟地址,所以系统必须把页目录和页表映射到地址空间中。对应4G地址空间的1024个页表被顺序映射到了从0xC0000000到0xC03FFFFF的4M地址空间。对应第一个4M地址空间的页表,被映射到了0xC0000000开始的第一个4K地址空间(0xC0000000开始的4K)。对应第二个4M地址空间的页表,被映射到了0xC0000000开始的第二个4K地址空间(0xC0001000开始的4K),以此类推。页目录被映射到了0xC0300000开始处的4K地址空间。0xC0000000到0xC03FFFFF的4M地址空间位于高2G的系统地址空间内,需要ring0的权限才能访问。<br> 有效页目录项和有效页表项<br> 页目录项和页表项的最低位,第0位,指明了一页是否映射了物理内存。最低位为1,有效(Valid),表示该页映射了物理内存。页目录项和页表项,4个字节,32bit,有着差不多的结构。使用 Win2k DDK 所附带的内核调试器,Kernel Debugger (KD) ,我们可以得到有效的页目录项和页表项的结构定义,对于使用 X86 CPU 的系统,该结构定义如下<br> !strct HARDWARE_PTE_X86<br> struct _HARDWARE_PTE_X86 (sizeof=4)<br> +0 bits0-0 Valid<br> +0 bits1-1 Write<br> +0 bits2-2 Owner<br> +0 bits3-3 WriteThrough<br> +0 bits4-4 CacheDisable<br> +0 bits5-5 Accessed<br> +0 bits6-6 Dirty<br> +0 bits7-7 LargePage<br> +0 bits8-8 Global<br> +0 bits9-9 CopyOnWrite<br> +0 bits10-10 Prototype<br> +0 bits11-11 reserved<br> +0 bits12-31 PageFrameNumber<br> bits12-31 PageFrameNumber:<br> 页目录项或者页表项的第12到第31位,长20位。物理页的页帧号。(将这32位和0xFFFFF000做与运算,就得到了该4KB物理页第一个字节的地址)由于页的大小是4KB,所以只需要20位,就可以寻址4G大小范围内的每一页。对于页目录项来说,所得的物理页中放着的是一个页表。<br> bits0-0 Valid: <br> 为0无效,该页没有映射物理内存。为1有效。该页映射了物理内存。<br> bits1-1 Write:<br> 为0该页只读。为1该页可以读写。<br> bits2-2 Owner:<br> 为0访问该页需要ring0权限,只有核心态(kernel-mode)的代码才可以访问。<br> 为1访问该页ring3权限就可以,用户态(user-mode)代码就可以访问。<br> bits3-3 WriteThrough:<br> 为0 对相关页使用 write-back caching 策略。为1 对相关页使用 write-through caching 策略。<br> 直写式(Write-through),在CPU向Cache写入的同时,也把数据写入相应内存单元。保证Cache和内存中相应单元数据的一致性。直写式速度慢,而且有些操作是不必要的,比如CPU连续多次更新一个Cache单元的内容,将导致相应内存单元连续多次被写入,而效果其实和写入最后一次更新是一样的。<br> 回写式(Write-back),CPU修改了Cache的内容后,并不立即修改内存中相应的单元。只有当回写操作被执行的时候,才修改相应内存单元。比如该Cache单元的内容从Cache中撤销时触发回写操作。回写式速度快,也避免了一些不必要的操作。<br> 如果CR0中的CD (cache disable)标志为1,则处理器忽略WriteThrough标志。CD标志,CR0寄存器的第30bit<br> 。观察发现,初始化之后的Win2k中,该位为0。也就是说页目录项和页表项中的WriteThrough标志是起作用的。<br> bits4-4 CacheDisable:<br> 为0 允许Cache该页。为1 禁止Cache该页。<br> 如果CR0中的CD (cache disable)标志为1,则处理器忽略CacheDisable标志。CD标志,CR0寄存器的第30bit<br> 。观察发现,初始化之后的Win2k中,该位为0。也就是说页目录项和页表项中的CacheDisable标志是起作用的。<br> bits5-5 Accessed:<br> 为0 该页没有被访问(读出或者写入)过。为1 该页被访问(读出或者写入)过。<br> bits6-6 Dirty:<br> 为0 该页中的内容没有被改动过。 为1 该页中的内容已经被改动过了(被写过)。<br> bits7-7 LargePage:<br> 为0 表示页大小为4K,为1 表示页大小为4M。<br> bits8-8 Global:<br> 为0 表示不是 global page。为1 表示是一个 global page。<br> 如果CR4中的 page global enable (PGE) 标志为1 ,表示允许 page global,那么当进程转换时在 TLB(Translation lookaside buffer ) 高速缓存中的 global page 不会失效。用来防止常用页(比如内核或者操作系统的执行代码所在页)被换出TLB高速缓存。寄存器CR4的PGE标志是第7位。观察发现,初始化之后的Win2k中,该位为1。<br> bits9-9 CopyOnWrite:<br> 用于 Copy-on-Write 机制。<br> bits10-10 Prototype:<br> 用于 进程间内存共享 机制。<br> bits11-11 reserved:<br> 保留<br> 页目录和页表<br> 我们可以使用 SoftICE 获得指定进程的页目录,方法如下,首先不加参数的 addr 命令,将列出当前系统中的进程。然后 addr 进程名 ,切换到该进程的地址空间。然后 dd c0300000 l 1000 ,将会在命令窗口输出0xc0300000处的0x1000字节(16进制,也就是4K字节)。然后退出 SoftICE,使用 Symbol Loader 的菜单中的 File -> Save SoftICE History AS.. 就可以把刚才输出的内容保存到文件中。每个进程的页目录都映射到了0xc0300000处,所以我们就得到了页目录的内容。<br> 我也写了一个叫 JiurlPdPtSee 的程序,可以输出指定进程的页目录和页表。以下的内容就来自这个程序。<br> 打开的一个记事本进程的页目录:<br> c0300000: 05f5b067 058ae067 067b5067 00eae067<br> c0300010: 03bfa067 00000000 00000000 00000000<br> c0300020: 00000000 00000000 00000000 00000000<br> c0300030: 00000000 00000000 00000000 00000000<br> c0300040: 00000000 00000000 00000000 00000000<br> c0300050: 00000000 00000000 00000000 00000000<br> c0300060: 00000000 00000000 00000000 00000000<br> c0300070: 00000000 00000000 00000000 00000000<br> c0300080: 00000000 00000000 00000000 00000000<br> c0300090: 00000000 00000000 00000000 00000000<br> c03000a0: 00000000 00000000 00000000 00000000<br> c03000b0: 00000000 00000000 00000000 00000000<br> c03000c0: 00000000 00000000 00000000 00000000<br> c03000d0: 00000000 00000000 00000000 00000000<br> c03000e0: 00000000 00000000 00000000 00000000<br> c03000f0: 00000000 00000000 00000000 00000000<br> c0300100: 043b1067 00000000 00000000 00000000<br> c0300110: 00000000 00000000 00000000 00000000<br> c0300120: 00000000 00000000 00000000 00000000<br> c0300130: 00000000 00000000 00000000 00000000<br> c0300140: 00000000 00000000 00000000 00000000<br> c0300150: 00000000 00000000 00000000 00000000<br> c0300160: 00000000 00000000 00000000 00000000<br> c0300170: 00000000 00000000 00000000 00000000<br> c0300180: 00000000 00000000 00000000 00000000<br> c0300190: 00000000 00000000 00000000 00000000<br> c03001a0: 00000000 00000000 00000000 00000000<br> c03001b0: 00000000 00000000 00000000 00000000<br> c03001c0: 00000000 00000000 00000000 00000000<br> c03001d0: 00000000 00000000 00000000 00000000<br> c03001e0: 00000000 00000000 00000000 00000000<br> c03001f0: 00000000 00000000 00000000 00000000<br> c0300200: 00000000 00000000 00000000 00000000<br> c0300210: 00000000 00000000 00000000 00000000<br> c0300220: 00000000 00000000 00000000 00000000<br> c0300230: 00000000 00000000 00000000 00000000<br> c0300240: 00000000 00000000 00000000 00000000<br> c0300250: 00000000 00000000 00000000 00000000<br> c0300260: 00000000 00000000 00000000 00000000<br> c0300270: 00000000 00000000 00000000 00000000<br> c0300280: 00000000 00000000 00000000 00000000<br> c0300290: 00000000 00000000 00000000 00000000<br> c03002a0: 00000000 00000000 00000000 00000000<br> c03002b0: 00000000 00000000 00000000 00000000<br> c03002c0: 00000000 00000000 00000000 00000000<br> c03002d0: 00000000 00000000 00000000 00000000<br> c03002e0: 00000000 00000000 00000000 00000000<br> c03002f0: 00000000 00000000 00000000 00000000<br> c0300300: 00000000 00000000 00000000 00000000<br> c0300310: 00000000 00000000 00000000 00000000<br> c0300320: 00000000 00000000 00000000 00000000<br> c0300330: 00000000 00000000 00000000 00000000<br> c0300340: 00000000 00000000 00000000 00000000<br> c0300350: 00000000 00000000 00000000 00000000<br> c0300360: 00000000 00000000 00000000 00000000<br> c0300370: 00000000 00000000 00000000 00000000<br> c0300380: 00000000 00000000 00000000 00000000<br> c0300390: 00000000 00000000 00000000 00000000<br> c03003a0: 00000000 00000000 00000000 00000000<br> c03003b0: 00000000 00000000 00000000 00000000<br> c03003c0: 00000000 00000000 00000000 00000000<br> c03003d0: 00000000 00000000 00000000 00000000<br> c03003e0: 00000000 00000000 00000000 00000000<br> c03003f0: 00000000 00000000 00000000 00000000<br> c0300400: 00000000 00000000 00000000 00000000<br> c0300410: 00000000 00000000 00000000 00000000<br> c0300420: 00000000 00000000 00000000 00000000<br> c0300430: 00000000 00000000 00000000 00000000<br> c0300440: 00000000 00000000 00000000 00000000<br> c0300450: 00000000 00000000 00000000 00000000<br> c0300460: 00000000 00000000 00000000 00000000<br> c0300470: 00000000 00000000 00000000 00000000<br> c0300480: 00000000 00000000 00000000 00000000<br> c0300490: 00000000 00000000 00000000 00000000<br> c03004a0: 00000000 00000000 00000000 00000000<br> c03004b0: 00000000 00000000 00000000 00000000<br> c03004c0: 00000000 00000000 00000000 00000000<br> c03004d0: 00000000 00000000 00000000 00000000<br> c03004e0: 00000000 00000000 00000000 00000000<br> c03004f0: 00000000 00000000 00000000 00000000<br> c0300500: 00000000 00000000 00000000 00000000<br> c0300510: 00000000 00000000 00000000 00000000<br> c0300520: 00000000 00000000 00000000 00000000<br> c0300530: 00000000 00000000 00000000 00000000<br> c0300540: 00000000 00000000 00000000 00000000<br> c0300550: 00000000 00000000 00000000 00000000<br> c0300560: 00000000 00000000 00000000 00000000<br> c0300570: 00000000 00000000 00000000 00000000<br> c0300580: 00000000 00000000 00000000 00000000<br> c0300590: 00000000 00000000 00000000 00000000<br> c03005a0: 00000000 00000000 00000000 00000000<br> c03005b0: 00000000 00000000 00000000 00000000<br> c03005c0: 00000000 00000000 00000000 00000000<br> c03005d0: 00000000 00000000 00000000 00000000<br> c03005e0: 00000000 00000000 00000000 00000000<br> c03005f0: 00000000 00000000 00000000 00000000<br> c0300600: 00000000 00000000 00000000 00000000<br> c0300610: 00000000 00000000 00000000 00000000<br> c0300620: 00000000 00000000 00000000 00000000<br> c0300630: 00000000 00000000 00000000 00000000<br> c0300640: 00000000 00000000 00000000 00000000<br> c0300650: 00000000 00000000 00000000 00000000<br> c0300660: 00000000 00000000 00000000 00000000<br> c0300670: 00000000 00000000 00000000 00000000<br> c0300680: 00000000 00000000 00000000 00000000<br> c0300690: 00000000 00000000 00000000 00000000<br> c03006a0: 00000000 00000000 00000000 00000000<br> c03006b0: 00000000 00000000 00000000 00000000<br> c03006c0: 00000000 00000000 00000000 00000000<br> c03006d0: 00000000 00000000 00000000 0423a067<br> c03006e0: 00000000 00000000 00000000 00000000<br> c03006f0: 00000000 00000000 00000000 00000000<br> c0300700: 00000000 00000000 00000000 00000000<br> c0300710: 00000000 00000000 00000000 00000000<br> c0300720: 00000000 00000000 00000000 00000000<br> c0300730: 00000000 00000000 00000000 00000000<br> c0300740: 00000000 00000000 00000000 00000000<br> c0300750: 00000000 00000000 00000000 0154b067<br> c0300760: 00000000 00000000 01fa4067 00000000<br> c0300770: 00000000 03946067 06825067 00d00067<br> c0300780: 01cc7067 00000000 00000000 00000000<br> c0300790: 00000000 00000000 00000000 00000000<br> c03007a0: 00000000 00000000 00000000 00000000<br> c03007b0: 00000000 00000000 00000000 00000000<br> c03007c0: 00000000 00000000 00000000 00000000<br> c03007d0: 00000000 00000000 00000000 00000000<br> c03007e0: 00000000 00000000 00000000 00000000<br> c03007f0: 00000000 02869067 00000000 07b98067<br> c0300800: 000001e3 004001e3 008001e3 00c001e3<br> c0300810: 010001e3 014001e3 018001e3 01c001e3<br> c0300820: 020001e3 024001e3 028001e3 02c001e3<br> c0300830: 030001e3 034001e3 038001e3 03c001e3<br> c0300840: 040001e3 044001e3 048001e3 04c001e3<br> c0300850: 050001e3 054001e3 058001e3 05c001e3<br> c0300860: 060001e3 064001e3 068001e3 06c001e3<br> c0300870: 070001e3 074001e3 078001e3 07c001e3<br> c0300880: 080001e3 084001e3 088001e3 08c001e3<br> c0300890: 090001e3 094001e3 098001e3 09c001e3<br> c03008a0: 0a0001e3 0a4001e3 0a8001e3 0ac001e3<br> c03008b0: 0b0001e3 0b4001e3 0b8001e3 0bc001e3<br> c03008c0: 0c0001e3 0c4001e3 0c8001e3 0cc001e3<br> c03008d0: 0d0001e3 0d4001e3 0d8001e3 0dc001e3<br> c03008e0: 0e0001e3 0e4001e3 0e8001e3 0ec001e3<br> c03008f0: 0f0001e3 0f4001e3 0f8001e3 0fc001e3<br> c0300900: 100001e3 104001e3 108001e3 10c001e3<br> c0300910: 110001e3 114001e3 118001e3 11c001e3<br> c0300920: 120001e3 124001e3 128001e3 12c001e3<br> c0300930: 130001e3 134001e3 138001e3 13c001e3<br> c0300940: 140001e3 144001e3 148001e3 14c001e3<br> c0300950: 150001e3 154001e3 158001e3 15c001e3<br> c0300960: 160001e3 164001e3 168001e3 16c001e3<br> c0300970: 170001e3 174001e3 178001e3 17c001e3<br> c0300980: 180001e3 184001e3 188001e3 18c001e3<br> c0300990: 190001e3 194001e3 198001e3 19c001e3<br> c03009a0: 1a0001e3 1a4001e3 1a8001e3 1ac001e3<br> c03009b0: 1b0001e3 1b4001e3 1b8001e3 1bc001e3<br> c03009c0: 1c0001e3 1c4001e3 1c8001e3 1cc001e3<br> c03009d0: 1d0001e3 1d4001e3 1d8001e3 1dc001e3<br> c03009e0: 1e0001e3 1e4001e3 1e8001e3 1ec001e3<br> c03009f0: 1f0001e3 1f4001e3 1f8001e3 1fc001e3<br> c0300a00: 06470163 00000000 00000000 00000000<br> c0300a10: 00000000 00000000 00000000 00000000<br> c0300a20: 00000000 00000000 00000000 00000000<br> c0300a30: 00000000 00000000 00000000 00000000<br> c0300a40: 016f1163 016f2163 016f3163 016f4163<br> c0300a50: 016f5163 016f6163 016d7163 016d8163<br> c0300a60: 016d9163 016da163 016db163 016dc163<br> c0300a70: 016dd163 016de163 016df163 01740163<br> c0300a80: 01701163 01702163 01703163 01704163<br> c0300a90: 01705163 01706163 01707163 01708163<br> c0300aa0: 01709163 0170a163 0170b163 0170c163<br> c0300ab0: 0170d163 0170e163 0170f163 01710163<br> c0300ac0: 01711163 01712163 01713163 01714163<br> c0300ad0: 01715163 01716163 016f7163 016f8163<br> c0300ae0: 016f9163 016fa163 016fb163 016fc163<br> c0300af0: 016fd163 016fe163 016ff163 01760163<br> c0300b00: 01721163 01722163 01723163 01724163<br> c0300b10: 01725163 01726163 01727163 01728163<br> c0300b20: 01729163 0172a163 0172b163 0172c163<br> c0300b30: 0172d163 0172e163 0172f163 01730163<br> c0300b40: 01731163 01732163 01733163 01734163<br> c0300b50: 01735163 01736163 01717163 01718163<br> c0300b60: 01719163 0171a163 0171b163 0171c163<br> c0300b70: 0171d163 0171e163 0171f163 01780163<br> c0300b80: 01741163 01742163 01743163 01744163<br> c0300b90: 01745163 01746163 01747163 01748163<br> c0300ba0: 01749163 0174a163 0174b163 0174c163<br> c0300bb0: 0174d163 0174e163 0174f163 01750163<br> c0300bc0: 01751163 01752163 01753163 01754163<br> c0300bd0: 01755163 01756163 01737163 01738163<br> c0300be0: 01739163 0173a163 0173b163 0173c163<br> c0300bf0: 0173d163 0173e163 0173f163 017a0163<br> c0300c00: 05cf0063 04a11063 00000000 01670163<br> c0300c10: 01671163 01672163 01673163 01674163<br> c0300c20: 01675163 01676163 01657163 01658163<br> c0300c30: 01659163 0165a163 0165b163 0165c163<br> c0300c40: 0165d163 0165e163 0165f163 016c0163<br> c0300c50: 01681163 01682163 01683163 01684163<br> c0300c60: 01685163 01686163 01687163 01688163<br> c0300c70: 01689163 0168a163 0168b163 0168c163<br> c0300c80: 0168d163 0168e163 0168f163 01690163<br> c0300c90: 01691163 01692163 01693163 01694163<br> c0300ca0: 01695163 01696163 01677163 01678163<br> c0300cb0: 01679163 0167a163 0167b163 0167c163<br> c0300cc0: 0167d163 0167e163 0167f163 016e0163<br> c0300cd0: 016a1163 016a2163 016a3163 016a4163<br> c0300ce0: 016a5163 016a6163 016a7163 016a8163<br> c0300cf0: 016a9163 016aa163 016ab163 016ac163<br> c0300d00: 016ad163 016ae163 016af163 016b0163<br> c0300d10: 016b1163 016b2163 016b3163 016b4163<br> c0300d20: 016b5163 016b6163 01697163 01698163<br> c0300d30: 01699163 0169a163 0169b163 0169c163<br> c0300d40: 0169d163 0169e163 0169f163 01700163<br> c0300d50: 016c1163 016c2163 016c3163 016c4163<br> c0300d60: 016c5163 016c6163 016c7163 016c8163<br> c0300d70: 016c9163 016ca163 016cb163 016cc163<br> c0300d80: 016cd163 016ce163 016cf163 016d0163<br> c0300d90: 016d1163 016d2163 016d3163 016d4163<br> c0300da0: 016d5163 016d6163 016b7163 016b8163<br> c0300db0: 016b9163 016ba163 016bb163 016bc163<br> c0300dc0: 016bd163 016be163 016bf163 01720163<br> c0300dd0: 016e1163 016e2163 016e3163 016e4163<br> c0300de0: 016e5163 016e6163 016e7163 016e8163<br> c0300df0: 016e9163 016ea163 016eb163 016ec163<br> c0300e00: 016ed163 016ee163 016ef163 016f0163<br> c0300e10: 01765163 026f6163 05189163 055ab163<br> c0300e20: 00000000 0740f163 05a71163 05f43163<br> c0300e30: 0090a163 0297e163 04867163 00000000<br> c0300e40: 00000000 00000000 00000000 00000000<br> c0300e50: 00000000 00000000 00000000 00000000<br> c0300e60: 00000000 00000000 00000000 00000000<br> c0300e70: 00000000 00000000 01768163 01769163<br> c0300e80: 0176a163 0176b163 0176c163 0176d163<br> c0300e90: 0176e163 0176f163 01770163 01771163<br> c0300ea0: 01772163 01773163 01774163 01775163<br> c0300eb0: 01776163 01757163 01758163 01759163<br> c0300ec0: 0175a163 0175b163 0175c163 0175d163<br> c0300ed0: 0175e163 0175f163 017c0163 01781163<br> c0300ee0: 01782163 01783163 01784163 01785163<br> c0300ef0: 01786163 01787163 01788163 01789163<br> c0300f00: 0178a163 01000163 01001163 01002163<br> c0300f10: 01003163 01004163 01005163 01006163<br> c0300f20: 01007163 01008163 01009163 0100a163<br> c0300f30: 0100b163 0100c163 0100d163 0100e163<br> c0300f40: 0100f163 01010163 01011163 01012163<br> c0300f50: 01013163 01014163 01015163 01016163<br> c0300f60: 01017163 01018163 01019163 0101a163<br> c0300f70: 0101b163 0101c163 0101d163 0101e163<br> c0300f80: 0101f163 01020163 01021163 01022163<br> c0300f90: 01023163 01024163 01025163 01026163<br> c0300fa0: 01027163 01028163 01029163 0102a163<br> c0300fb0: 0102b163 0102c163 0102d163 0102e163<br> c0300fc0: 0102f163 01030163 01031163 01032163<br> c0300fd0: 01033163 01034163 01035163 01036163<br> c0300fe0: 01037163 01038163 01039163 0103a163<br> c0300ff0: 0103b163 0103c163 0103d163 00031163<br> 我们来分析一下这个页目录。<br> 4G地址空间,低2G是用户空间,前512项页目录项用于这2G的地址转换。高2G是系统空间,后512项页目录项用于这2G的地址转换。每项32bit,第0bit是有效位,该位为0表示没有该项所对应的虚拟地址空间的页表。在前512项中我们看到了大量的00000000,最低位为0,表示这些项都没有页表。也就是说这项对应的4MB地址空间是没有物理内存映射的。我们看到了在用户地址空间中有大量的页是没有物理页的映射的,什么映射也没有是空的。我们再看另外一个进程的页目录,然后和这个做比较。<br> System 进程的页目录:<br> c0300000: 01860067 00000000 00000000 00000000<br> c0300010: 00000000 00000000 00000000 00000000<br> c0300020: 00000000 00000000 00000000 00000000<br> c0300030: 00000000 00000000 00000000 00000000<br> c0300040: 00000000 00000000 00000000 00000000<br> c0300050: 00000000 00000000 00000000 00000000<br> c0300060: 00000000 00000000 00000000 00000000<br> c0300070: 00000000 00000000 00000000 00000000<br> c0300080: 00000000 00000000 00000000 00000000<br> c0300090: 00000000 00000000 00000000 00000000<br> c03000a0: 00000000 00000000 00000000 00000000<br> c03000b0: 00000000 00000000 00000000 00000000<br> c03000c0: 00000000 00000000 00000000 00000000<br> c03000d0: 00000000 00000000 00000000 00000000<br> c03000e0: 00000000 00000000 00000000 00000000<br> c03000f0: 00000000 00000000 00000000 00000000<br> c0300100: 00000000 00000000 00000000 00000000<br> c0300110: 00000000 00000000 00000000 00000000<br> c0300120: 00000000 00000000 00000000 00000000<br> c0300130: 00000000 00000000 00000000 00000000<br> c0300140: 00000000 00000000 00000000 00000000<br> c0300150: 00000000 00000000 00000000 00000000<br> c0300160: 00000000 00000000 00000000 00000000<br> c0300170: 00000000 00000000 00000000 00000000<br> c0300180: 00000000 00000000 00000000 00000000<br> c0300190: 00000000 00000000 00000000 00000000<br> c03001a0: 00000000 00000000 00000000 00000000<br> c03001b0: 00000000 00000000 00000000 00000000<br> c03001c0: 00000000 00000000 00000000 00000000<br> c03001d0: 00000000 00000000 00000000 00000000<br> c03001e0: 00000000 00000000 00000000 00000000<br> c03001f0: 00000000 00000000 00000000 00000000<br> c0300200: 00000000 00000000 00000000 00000000<br> c0300210: 00000000 00000000 00000000 00000000<br> c0300220: 00000000 00000000 00000000 00000000<br> c0300230: 00000000 00000000 00000000 00000000<br> c0300240: 00000000 00000000 00000000 00000000<br> c0300250: 00000000 00000000 00000000 00000000<br> c0300260: 00000000 00000000 00000000 00000000<br> c0300270: 00000000 00000000 00000000 00000000<br> c0300280: 00000000 00000000 00000000 00000000<br> c0300290: 00000000 00000000 00000000 00000000<br> c03002a0: 00000000 00000000 00000000 00000000<br> c03002b0: 00000000 00000000 00000000 00000000<br> c03002c0: 00000000 00000000 00000000 00000000<br> c03002d0: 00000000 00000000 00000000 00000000<br> c03002e0: 00000000 00000000 00000000 00000000<br> c03002f0: 00000000 00000000 00000000 00000000<br> c0300300: 00000000 00000000 00000000 00000000<br> c0300310: 00000000 00000000 00000000 00000000<br> c0300320: 00000000 00000000 00000000 00000000<br> c0300330: 00000000 00000000 00000000 00000000<br> c0300340: 00000000 00000000 00000000 00000000<br> c0300350: 00000000 00000000 00000000 00000000<br> c0300360: 00000000 00000000 00000000 00000000<br> c0300370: 00000000 00000000 00000000 00000000<br> c0300380: 00000000 00000000 00000000 00000000<br> c0300390: 00000000 00000000 00000000 00000000<br> c03003a0: 00000000 00000000 00000000 00000000<br> c03003b0: 00000000 00000000 00000000 00000000<br> c03003c0: 00000000 00000000 00000000 00000000<br> c03003d0: 00000000 00000000 00000000 00000000<br> c03003e0: 00000000 00000000 00000000 00000000<br> c03003f0: 00000000 00000000 00000000 00000000<br> c0300400: 00000000 00000000 00000000 00000000<br> c0300410: 00000000 00000000 00000000 00000000<br> c0300420: 00000000 00000000 00000000 00000000<br> c0300430: 00000000 00000000 00000000 00000000<br> c0300440: 00000000 00000000 00000000 00000000<br> c0300450: 00000000 00000000 00000000 00000000<br> c0300460: 00000000 00000000 00000000 00000000<br> c0300470: 00000000 00000000 00000000 00000000<br> c0300480: 00000000 00000000 00000000 00000000<br> c0300490: 00000000 00000000 00000000 00000000<br> c03004a0: 00000000 00000000 00000000 00000000<br> c03004b0: 00000000 00000000 00000000 00000000<br> c03004c0: 00000000 00000000 00000000 00000000<br> c03004d0: 00000000 00000000 00000000 00000000<br> c03004e0: 00000000 00000000 00000000 00000000<br> c03004f0: 00000000 00000000 00000000 00000000<br> c0300500: 00000000 00000000 00000000 00000000<br> c0300510: 00000000 00000000 00000000 00000000<br> c0300520: 00000000 00000000 00000000 00000000<br> c0300530: 00000000 00000000 00000000 00000000<br> c0300540: 00000000 00000000 00000000 00000000<br> c0300550: 00000000 00000000 00000000 00000000<br> c0300560: 00000000 00000000 00000000 00000000<br> c0300570: 00000000 00000000 00000000 00000000<br> c0300580: 00000000 00000000 00000000 00000000<br> c0300590: 00000000 00000000 00000000 00000000<br> c03005a0: 00000000 00000000 00000000 00000000<br> c03005b0: 00000000 00000000 00000000 00000000<br> c03005c0: 00000000 00000000 00000000 00000000<br> c03005d0: 00000000 00000000 00000000 00000000<br> c03005e0: 00000000 00000000 00000000 00000000<br> c03005f0: 00000000 00000000 00000000 00000000<br> c0300600: 00000000 00000000 00000000 00000000<br> c0300610: 00000000 00000000 00000000 00000000<br> c0300620: 00000000 00000000 00000000 00000000<br> c0300630: 00000000 00000000 00000000 00000000<br> c0300640: 00000000 00000000 00000000 00000000<br> c0300650: 00000000 00000000 00000000 00000000<br> c0300660: 00000000 00000000 00000000 00000000<br> c0300670: 00000000 00000000 00000000 00000000<br> c0300680: 00000000 00000000 00000000 00000000<br> c0300690: 00000000 00000000 00000000 00000000<br> c03006a0: 00000000 00000000 00000000 00000000<br> c03006b0: 00000000 00000000 00000000 00000000<br> c03006c0: 00000000 00000000 00000000 00000000<br> c03006d0: 00000000 00000000 00000000 00000000<br> c03006e0: 00000000 00000000 00000000 00000000<br> c03006f0: 00000000 00000000 00000000 00000000<br> c0300700: 00000000 00000000 00000000 00000000<br> c0300710: 00000000 00000000 00000000 00000000<br> c0300720: 00000000 00000000 00000000 00000000<br> c0300730: 00000000 00000000 00000000 00000000<br> c0300740: 00000000 00000000 00000000 00000000<br> c0300750: 00000000 00000000 00000000 00000000<br> c0300760: 00000000 00000000 00000000 00000000<br> c0300770: 00000000 00000000 00000000 02119067<br> c0300780: 00000000 00000000 00000000 00000000<br> c0300790: 00000000 00000000 00000000 00000000<br> c03007a0: 00000000 00000000 00000000 00000000<br> c03007b0: 00000000 00000000 00000000 00000000<br> c03007c0: 00000000 00000000 00000000 00000000<br> c03007d0: 00000000 00000000 00000000 00000000<br> c03007e0: 00000000 00000000 00000000 00000000<br> c03007f0: 00000000 00000000 00000000 02138067<br> c0300800: 000001e3 004001e3 008001e3 00c001e3<br> c0300810: 010001e3 014001e3 018001e3 01c001e3<br> c0300820: 020001e3 024001e3 028001e3 02c001e3<br> c0300830: 030001e3 034001e3 038001e3 03c001e3<br> c0300840: 040001e3 044001e3 048001e3 04c001e3<br> c0300850: 050001e3 054001e3 058001e3 05c001e3<br> c0300860: 060001e3 064001e3 068001e3 06c001e3<br> c0300870: 070001e3 074001e3 078001e3 07c001e3<br> c0300880: 080001e3 084001e3 088001e3 08c001e3<br> c0300890: 090001e3 094001e3 098001e3 09c001e3<br> c03008a0: 0a0001e3 0a4001e3 0a8001e3 0ac001e3<br> c03008b0: 0b0001e3 0b4001e3 0b8001e3 0bc001e3<br> c03008c0: 0c0001e3 0c4001e3 0c8001e3 0cc001e3<br> c03008d0: 0d0001e3 0d4001e3 0d8001e3 0dc001e3<br> c03008e0: 0e0001e3 0e4001e3 0e8001e3 0ec001e3<br> c03008f0: 0f0001e3 0f4001e3 0f8001e3 0fc001e3<br> c0300900: 100001e3 104001e3 108001e3 10c001e3<br> c0300910: 110001e3 114001e3 118001e3 11c001e3<br> c0300920: 120001e3 124001e3 128001e3 12c001e3<br> c0300930: 130001e3 134001e3 138001e3 13c001e3<br> c0300940: 140001e3 144001e3 148001e3 14c001e3<br> c0300950: 150001e3 154001e3 158001e3 15c001e3<br> c0300960: 160001e3 164001e3 168001e3 16c001e3<br> c0300970: 170001e3 174001e3 178001e3 17c001e3<br> c0300980: 180001e3 184001e3 188001e3 18c001e3<br> c0300990: 190001e3 194001e3 198001e3 19c001e3<br> c03009a0: 1a0001e3 1a4001e3 1a8001e3 1ac001e3<br> c03009b0: 1b0001e3 1b4001e3 1b8001e3 1bc001e3<br> c03009c0: 1c0001e3 1c4001e3 1c8001e3 1cc001e3<br> c03009d0: 1d0001e3 1d4001e3 1d8001e3 1dc001e3<br> c03009e0: 1e0001e3 1e4001e3 1e8001e3 1ec001e3<br> c03009f0: 1f0001e3 1f4001e3 1f8001e3 1fc001e3<br> c0300a00: 06470163 06f15163 00000000 00000000<br> c0300a10: 00000000 00000000 00000000 00000000<br> c0300a20: 00000000 00000000 00000000 00000000<br> c0300a30: 00000000 00000000 00000000 00000000<br> c0300a40: 016f1163 016f2163 016f3163 016f4163<br> c0300a50: 016f5163 016f6163 016d7163 016d8163<br> c0300a60: 016d9163 016da163 016db163 016dc163<br> c0300a70: 016dd163 016de163 016df163 01740163<br> c0300a80: 01701163 01702163 01703163 01704163<br> c0300a90: 01705163 01706163 01707163 01708163<br> c0300aa0: 01709163 0170a163 0170b163 0170c163<br> c0300ab0: 0170d163 0170e163 0170f163 01710163<br> c0300ac0: 01711163 01712163 01713163 01714163<br> c0300ad0: 01715163 01716163 016f7163 016f8163<br> c0300ae0: 016f9163 016fa163 016fb163 016fc163<br> c0300af0: 016fd163 016fe163 016ff163 01760163<br> c0300b00: 01721163 01722163 01723163 01724163<br> c0300b10: 01725163 01726163 01727163 01728163<br> c0300b20: 01729163 0172a163 0172b163 0172c163<br> c0300b30: 0172d163 0172e163 0172f163 01730163<br> c0300b40: 01731163 01732163 01733163 01734163<br> c0300b50: 01735163 01736163 01717163 01718163<br> c0300b60: 01719163 0171a163 0171b163 0171c163<br> c0300b70: 0171d163 0171e163 0171f163 01780163<br> c0300b80: 01741163 01742163 01743163 01744163<br> c0300b90: 01745163 01746163 01747163 01748163<br> c0300ba0: 01749163 0174a163 0174b163 0174c163<br> c0300bb0: 0174d163 0174e163 0174f163 01750163<br> c0300bc0: 01751163 01752163 01753163 01754163<br> c0300bd0: 01755163 01756163 01737163 01738163<br> c0300be0: 01739163 0173a163 0173b163 0173c163<br> c0300bf0: 0173d163 0173e163 0173f163 017a0163<br> c0300c00: 00030067 01520063 00000000 01670163<br> c0300c10: 01671163 01672163 01673163 01674163<br> c0300c20: 01675163 01676163 01657163 01658163<br> c0300c30: 01659163 0165a163 0165b163 0165c163<br> c0300c40: 0165d163 0165e163 0165f163 016c0163<br> c0300c50: 01681163 01682163 01683163 01684163<br> c0300c60: 01685163 01686163 01687163 01688163<br> c0300c70: 01689163 0168a163 0168b163 0168c163<br> c0300c80: 0168d163 0168e163 0168f163 01690163<br> c0300c90: 01691163 01692163 01693163 01694163<br> c0300ca0: 01695163 01696163 01677163 01678163<br> c0300cb0: 01679163 0167a163 0167b163 0167c163<br> c0300cc0: 0167d163 0167e163 0167f163 016e0163<br> c0300cd0: 016a1163 016a2163 016a3163 016a4163<br> c0300ce0: 016a5163 016a6163 016a7163 016a8163<br> c0300cf0: 016a9163 016aa163 016ab163 016ac163<br> c0300d00: 016ad163 016ae163 016af163 016b0163<br> c0300d10: 016b1163 016b2163 016b3163 016b4163<br> c0300d20: 016b5163 016b6163 01697163 01698163<br> c0300d30: 01699163 0169a163 0169b163 0169c163<br> c0300d40: 0169d163 0169e163 0169f163 01700163<br> c0300d50: 016c1163 016c2163 016c3163 016c4163<br> c0300d60: 016c5163 016c6163 016c7163 016c8163<br> c0300d70: 016c9163 016ca163 016cb163 016cc163<br> c0300d80: 016cd163 016ce163 016cf163 016d0163<br> c0300d90: 016d1163 016d2163 016d3163 016d4163<br> c0300da0: 016d5163 016d6163 016b7163 016b8163<br> c0300db0: 016b9163 016ba163 016bb163 016bc163<br> c0300dc0: 016bd163 016be163 016bf163 01720163<br> c0300dd0: 016e1163 016e2163 016e3163 016e4163<br> c0300de0: 016e5163 016e6163 016e7163 016e8163<br> c0300df0: 016e9163 016ea163 016eb163 016ec163<br> c0300e00: 016ed163 016ee163 016ef163 016f0163<br> c0300e10: 01765163 026f6163 05189163 055ab163<br> c0300e20: 059ad163 0740f163 05a71163 05f43163<br> c0300e30: 0090a163 0297e163 04867163 034ae163<br> c0300e40: 00000300 00000300 00000300 00000300<br> c0300e50: 00000300 00000300 00000300 00000300<br> c0300e60: 00000300 00000300 00000300 00000300<br> c0300e70: 00000300 00000300 01768163 01769163<br> c0300e80: 0176a163 0176b163 0176c163 0176d163<br> c0300e90: 0176e163 0176f163 01770163 01771163<br> c0300ea0: 01772163 01773163 01774163 01775163<br> c0300eb0: 01776163 01757163 01758163 01759163<br> c0300ec0: 0175a163 0175b163 0175c163 0175d163<br> c0300ed0: 0175e163 0175f163 017c0163 01781163<br> c0300ee0: 01782163 01783163 01784163 01785163<br> c0300ef0: 01786163 01787163 01788163 01789163<br> c0300f00: 0178a163 01000163 01001163 01002163<br> c0300f10: 01003163 01004163 01005163 01006163<br> c0300f20: 01007163 01008163 01009163 0100a163<br> c0300f30: 0100b163 0100c163 0100d163 0100e163<br> c0300f40: 0100f163 01010163 01011163 01012163<br> c0300f50: 01013163 01014163 01015163 01016163<br> c0300f60: 01017163 01018163 01019163 0101a163<br> c0300f70: 0101b163 0101c163 0101d163 0101e163<br> c0300f80: 0101f163 01020163 01021163 01022163<br> c0300f90: 01023163 01024163 01025163 01026163<br> c0300fa0: 01027163 01028163 01029163 0102a163<br> c0300fb0: 0102b163 0102c163 0102d163 0102e163<br> c0300fc0: 0102f163 01030163 01031163 01032163<br> c0300fd0: 01033163 01034163 01035163 01036163<br> c0300fe0: 01037163 01038163 01039163 0103a163<br> c0300ff0: 0103b163 0103c163 0103d163 00031163<br> 我们再来分析。<br> 这是系统进程的页目录。首先在用户地址空间中,是大片的没有物理内存映射。<br> 然后我们用UltraEdit把两个页目录做比较。发现两个进程的用户地址空间(低2G,前512项)中没有同一位置的有效项,这说明了,每个进程有自己独立的用户地址空间,各自映射不同的物理内存。而系统地址空间(高2G,后512项)的比较结果是绝大部分项的内容是一样的。页目录项一样的话,该项对应的页表,将在同一个物理页上,也就是页表肯定也是同一个。那么页表相应的物理页也就是同一个。说明两个进程的系统地址空间中绝大部分内容是一样的。c0300c00处的页目录项对应的是,页表和页目录所在的4M地址空间,每个进程的页目录和页表的内容不同,所以他们当然在不同的物理页,比较的结果也是不同的。<br> 我们再来看看页表中的内容,我们选择的是刚才那个记事本进程的页目录中的页目录项1(页目录内偏移+4处的页目录项)对应的页表。<br> 记事本进程页目录项1对应的页表:<br> c0001000: 00000000 00000000 00000000 00000000<br> c0001010: 00000000 00000000 00000000 00000000<br> c0001020: 00000000 00000000 00000000 00000000<br> c0001030: 00000000 00000000 0464f025 046dd025<br> c0001040: 00000000 00000000 00000000 00000000<br> c0001050: 00000000 00000000 00000000 00000000<br> c0001060: 00000000 00000000 00000000 00000000<br> c0001070: 00000000 00000000 00000000 00000000<br> c0001080: 00000000 00000000 00000000 00000000<br> c0001090: 00000000 00000000 00000000 00000000<br> c00010a0: 00000000 00000000 00000000 00000000<br> c00010b0: 00000000 00000000 00000000 00000000<br> c00010c0: 00000000 00000000 00000000 00000000<br> c00010d0: 00000000 00000000 00000000 00000000<br> c00010e0: 00000000 00000000 00000000 00000000<br> c00010f0: 00000000 00000000 00000000 00000000<br> c0001100: 00000000 00000000 00000000 00000000<br> c0001110: 00000000 00000000 00000000 00000000<br> c0001120: 00000000 00000000 00000000 00000000<br> c0001130: 00000000 00000000 00000000 00000000<br> c0001140: 00000000 00000000 00000000 00000000<br> c0001150: 00000000 00000000 00000000 00000000<br> c0001160: 00000000 00000000 00000000 00000000<br> c0001170: 00000000 00000000 00000000 00000000<br> c0001180: 00000000 00000000 00000000 00000000<br> c0001190: 00000000 00000000 00000000 00000000<br> c00011a0: 00000000 00000000 00000000 00000000<br> c00011b0: 00000000 00000000 00000000 00000000<br> c00011c0: 00000000 00000000 00000000 00000000<br> c00011d0: 00000000 00000000 00000000 00000000<br> c00011e0: 00000000 00000000 00000000 00000000<br> c00011f0: 00000000 00000000 00000000 00000000<br> c0001200: 00000000 00000000 00000000 00000000<br> c0001210: 00000000 00000000 00000000 00000000<br> c0001220: 00000000 00000000 00000000 00000000<br> c0001230: 00000000 00000000 00000000 00000000<br> c0001240: 00000000 00000000 00000000 00000000<br> c0001250: 00000000 00000000 00000000 00000000<br> c0001260: 00000000 00000000 00000000 00000000<br> c0001270: 00000000 00000000 00000000 00000000<br> c0001280: 00000000 00000000 00000000 00000000<br> c0001290: 00000000 00000000 00000000 00000000<br> c00012a0: 00000000 00000000 00000000 00000000<br> c00012b0: 00000000 00000000 00000000 00000000<br> c00012c0: 00000000 00000000 00000000 00000000<br> c00012d0: 00000000 00000000 00000000 00000000<br> c00012e0: 00000000 00000000 00000000 00000000<br> c00012f0: 00000000 00000000 00000000 00000000<br> c0001300: 00000000 00000000 00000000 00000000<br> c0001310: 00000000 00000000 00000000 00000000<br> c0001320: 00000000 00000000 00000000 00000000<br> c0001330: 00000000 00000000 00000000 00000000<br> c0001340: 00000000 00000000 00000000 00000000<br> c0001350: 00000000 00000000 00000000 00000000<br> c0001360: 00000000 00000000 00000000 00000000<br> c0001370: 00000000 00000000 00000000 00000000<br> c0001380: 00000000 00000000 00000000 00000000<br> c0001390: 00000000 00000000 00000000 00000000<br> c00013a0: 00000000 00000000 00000000 00000000<br> c00013b0: 00000000 00000000 00000000 00000000<br> c00013c0: 00000000 00000000 00000000 00000000<br> c00013d0: 00000000 00000000 00000000 00000000<br> c00013e0: 00000000 00000000 00000000 00000000<br> c00013f0: 00000000 00000000 00000000 00000000<br> c0001400: 00000000 00000000 00000000 00000000<br> c0001410: 00000000 00000000 00000000 00000000<br> c0001420: 00000000 00000000 00000000 00000000<br> c0001430: 00000000 00000000 00000000 00000000<br> c0001440: 00000000 00000000 00000000 00000000<br> c0001450: 00000000 00000000 00000000 00000000<br> c0001460: 00000000 00000000 00000000 00000000<br> c0001470: 00000000 00000000 00000000 00000000<br> c0001480: 00000000 00000000 00000000 00000000<br> c0001490: 00000000 00000000 00000000 00000000<br> c00014a0: 00000000 00000000 00000000 00000000<br> c00014b0: 00000000 00000000 00000000 00000000<br> c00014c0: 00000000 00000000 00000000 00000000<br> c00014d0: 00000000 00000000 00000000 00000000<br> c00014e0: 00000000 00000000 00000000 00000000<br> c00014f0: 00000000 00000000 00000000 00000000<br> c0001500: 00000000 00000000 00000000 00000000<br> c0001510: 00000000 00000000 00000000 00000000<br> c0001520: 00000000 00000000 00000000 00000000<br> c0001530: 00000000 00000000 00000000 00000000<br> c0001540: 00000000 00000000 00000000 00000000<br> c0001550: 00000000 00000000 00000000 00000000<br> c0001560: 00000000 00000000 00000000 00000000<br> c0001570: 00000000 00000000 00000000 00000000<br> c0001580: 00000000 00000000 00000000 00000000<br> c0001590: 00000000 00000000 00000000 00000000<br> c00015a0: 00000000 00000000 00000000 00000000<br> c00015b0: 00000000 00000000 00000000 00000000<br> c00015c0: 00000000 00000000 00000000 00000000<br> c00015d0: 00000000 00000000 00000000 00000000<br> c00015e0: 00000000 00000000 00000000 00000000<br> c00015f0: 00000000 00000000 00000000 00000000<br> c0001600: 00000000 00000000 00000000 00000000<br> c0001610: 00000000 00000000 00000000 00000000<br> c0001620: 00000000 00000000 00000000 00000000<br> c0001630: 00000000 00000000 00000000 00000000<br> c0001640: 00000000 00000000 00000000 00000000<br> c0001650: 00000000 00000000 00000000 00000000<br> c0001660: 00000000 00000000 00000000 00000000<br> c0001670: 00000000 00000000 00000000 00000000<br> c0001680: 00000000 00000000 00000000 00000000<br> c0001690: 00000000 00000000 00000000 00000000<br> c00016a0: 00000000 00000000 00000000 00000000<br> c00016b0: 00000000 00000000 00000000 00000000<br> c00016c0: 00000000 00000000 00000000 00000000<br> c00016d0: 00000000 00000000 00000000 00000000<br> c00016e0: 00000000 00000000 00000000 00000000<br> c00016f0: 00000000 00000000 00000000 00000000<br> c0001700: 00000000 00000000 00000000 00000000<br> c0001710: 00000000 00000000 00000000 00000000<br> c0001720: 00000000 00000000 00000000 00000000<br> c0001730: 00000000 00000000 00000000 00000000<br> c0001740: 00000000 00000000 00000000 00000000<br> c0001750: 00000000 00000000 00000000 00000000<br> c0001760: 00000000 00000000 00000000 00000000<br> c0001770: 00000000 00000000 00000000 00000000<br> c0001780: 00000000 00000000 00000000 00000000<br> c0001790: 00000000 00000000 00000000 00000000<br> c00017a0: 00000000 00000000 00000000 00000000<br> c00017b0: 00000000 00000000 00000000 00000000<br> c00017c0: 00000000 00000000 00000000 00000000<br> c00017d0: 00000000 00000000 00000000 00000000<br> c00017e0: 00000000 00000000 00000000 00000000<br> c00017f0: 00000000 00000000 00000000 00000000<br> c0001800: 00000000 00000000 00000000 00000000<br> c0001810: 00000000 00000000 00000000 00000000<br> c0001820: 00000000 00000000 00000000 00000000<br> c0001830: 00000000 00000000 00000000 00000000<br> c0001840: 00000000 00000000 00000000 00000000<br> c0001850: 00000000 00000000 00000000 00000000<br> c0001860: 00000000 00000000 00000000 00000000<br> c0001870: 00000000 00000000 00000000 00000000<br> c0001880: 00000000 00000000 00000000 00000000<br> c0001890: 00000000 00000000 00000000 00000000<br> c00018a0: 00000000 00000000 00000000 00000000<br> c00018b0: 00000000 00000000 00000000 00000000<br> c00018c0: 00000000 00000000 00000000 00000000<br> c00018d0: 00000000 00000000 00000000 00000000<br> c00018e0: 00000000 00000000 00000000 00000000<br> c00018f0: 00000000 00000000 00000000 00000000<br> c0001900: 00000000 00000000 00000000 00000000<br> c0001910: 00000000 00000000 00000000 00000000<br> c0001920: 00000000 00000000 00000000 00000000<br> c0001930: 00000000 00000000 00000000 00000000<br> c0001940: 00000000 00000000 00000000 00000000<br> c0001950: 00000000 00000000 00000000 00000000<br> c0001960: 00000000 00000000 00000000 00000000<br> c0001970: 00000000 00000000 00000000 00000000<br> c0001980: 00000000 00000000 00000000 00000000<br> c0001990: 00000000 00000000 00000000 00000000<br> c00019a0: 00000000 00000000 00000000 00000000<br> c00019b0: 00000000 00000000 00000000 00000000<br> c00019c0: 00000000 00000000 00000000 00000000<br> c00019d0: 00000000 00000000 00000000 00000000<br> c00019e0: 00000000 00000000 00000000 00000000<br> c00019f0: 00000000 00000000 00000000 00000000<br> c0001a00: 00000000 00000000 00000000 00000000<br> c0001a10: 00000000 00000000 00000000 00000000<br> c0001a20: 00000000 00000000 00000000 00000000<br> c0001a30: 00000000 00000000 00000000 00000000<br> c0001a40: 00000000 00000000 00000000 00000000<br> c0001a50: 00000000 00000000 00000000 00000000<br> c0001a60: 00000000 00000000 00000000 00000000<br> c0001a70: 00000000 00000000 00000000 00000000<br> c0001a80: 01fd8067 00000000 00000000 00000000<br> c0001a90: 00000000 00000000 00000000 00000000<br> c0001aa0: 00000000 00000000 00000000 00000000<br> c0001ab0: 00000000 00000000 00000000 00000000<br> c0001ac0: 02ed9047 00000000 00000000 00000000<br> c0001ad0: 00000000 00000000 00000000 00000000<br> c0001ae0: 00000000 00000000 00000000 00000000<br> c0001af0: 00000000 00000000 00000000 00000000<br> c0001b00: 05d3c047 0243d047 006de047 0217f047<br> c0001b10: 04f39047 0695a047 01c5b047 00000000<br> c0001b20: 00000000 00000000 00000000 00000000<br> c0001b30: 00000000 00000000 00000000 00000000<br> c0001b40: 07596005 07597005 00000000 00000000<br> c0001b50: 00000000 00000000 00000000 00000000<br> c0001b60: 00000000 00000000 00000000 00000000<br> c0001b70: 00000000 00000000 00000000 00000000<br> c0001b80: 0272a047 00000000 00000000 00000000<br> c0001b90: 00000000 00000000 00000000 00000000<br> c0001ba0: 00000000 00000000 00000000 00000000<br> c0001bb0: 00000000 00000000 00000000 00000000<br> c0001bc0: 06825047 00000000 00000000 00000000<br> c0001bd0: 00000000 00000000 00000000 00000000<br> c0001be0: 00000000 00000000 00000000 00000000<br> c0001bf0: 00000000 00000000 00000000 00000000<br> c0001c00: 00000000 00000000 00000000 00000000<br> c0001c10: 00000000 00000000 00000000 00000000<br> c0001c20: 00000000 00000000 00000000 00000000<br> c0001c30: 00000000 00000000 00000000 00000000<br> c0001c40: 00000000 00000000 00000000 00000000<br> c0001c50: 00000000 00000000 00000000 00000000<br> c0001c60: 00000000 00000000 00000000 00000000<br> c0001c70: 00000000 00000000 00000000 00000000<br> c0001c80: 00000000 00000000 00000000 00000000<br> c0001c90: 00000000 00000000 00000000 00000000<br> c0001ca0: 00000000 00000000 00000000 00000000<br> c0001cb0: 00000000 00000000 00000000 00000000<br> c0001cc0: 00000000 00000000 00000000 00000000<br> c0001cd0: 00000000 00000000 00000000 00000000<br> c0001ce0: 00000000 00000000 00000000 00000000<br> c0001cf0: 00000000 00000000 00000000 00000000<br> c0001d00: 00000000 00000000 00000000 00000000<br> c0001d10: 00000000 00000000 00000000 00000000<br> c0001d20: 00000000 00000000 00000000 00000000<br> c0001d30: 00000000 00000000 00000000 00000000<br> c0001d40: 00000000 00000000 00000000 00000000<br> c0001d50: 00000000 00000000 00000000 00000000<br> c0001d60: 00000000 00000000 00000000 00000000<br> c0001d70: 00000000 00000000 00000000 00000000<br> c0001d80: 00000000 00000000 00000000 00000000<br> c0001d90: 00000000 00000000 00000000 00000000<br> c0001da0: 00000000 00000000 00000000 00000000<br> c0001db0: 00000000 00000000 00000000 00000000<br> c0001dc0: 04daf047 03c90047 05ba1047 03de2047<br> c0001dd0: 00000000 00000000 00000000 00000000<br> c0001de0: 00000000 00000000 00000000 00000000<br> c0001df0: 00000000 00000000 00000000 00000000<br> c0001e00: 00ef1047 052d2047 05573047 065f4047<br> c0001e10: 01c55047 03a56047 03457047 045b8047<br> c0001e20: 076d9047 037ba047 04f3b047 0347c047<br> c0001e30: 033dd047 05a1e047 01dbf047 02220047<br> c0001e40: 00000000 00000000 00000000 00000000<br> c0001e50: 00000000 00000000 00000000 00000000<br> c0001e60: 00000000 00000000 00000000 00000000<br> c0001e70: 00000000 00000000 00000000 00000000<br> c0001e80: 00000000 00000000 00000000 00000000<br> c0001e90: 00000000 00000000 00000000 00000000<br> c0001ea0: 00000000 00000000 00000000 00000000<br> c0001eb0: 00000000 00000000 00000000 00000000<br> c0001ec0: 00000000 00000000 00000000 00000000<br> c0001ed0: 00000000 00000000 00000000 00000000<br> c0001ee0: 00000000 00000000 00000000 00000000<br> c0001ef0: 00000000 00000000 00000000 00000000<br> c0001f00: 00000000 00000000 00000000 00000000<br> c0001f10: 00000000 00000000 00000000 00000000<br> c0001f20: 00000000 00000000 00000000 00000000<br> c0001f30: 00000000 00000000 00000000 00000000<br> c0001f40: 00000000 00000000 00000000 00000000<br> c0001f50: 00000000 00000000 00000000 00000000<br> c0001f60: 00000000 00000000 00000000 00000000<br> c0001f70: 00000000 00000000 00000000 00000000<br> c0001f80: 00000000 00000000 00000000 00000000<br> c0001f90: 00000000 00000000 00000000 00000000<br> c0001fa0: 00000000 00000000 00000000 00000000<br> c0001fb0: 00000000 00000000 00000000 00000000<br> c0001fc0: 00000000 00000000 00000000 00000000<br> c0001fd0: 00000000 00000000 00000000 00000000<br> c0001fe0: 00000000 00000000 00000000 00000000<br> c0001ff0: 00000000 00000000 00000000 00000000<br> 分析一下这个页表,一个页表负责4MB地址空间。每个有效项表明该页被映射到了物理页。从这个页表中看到,有大量的项是没有物理页映射的。这4MB地址空间,只有一部分映射了物理内存。<br> 地址空间中的 Large Page 部分<br> 在页目录中我们可以看到从0xC0300800到0xC03009FC这128个页目录项的低12位值为0x1e3,也就是 111100011 。这些项的第7位, LargePage标志位,为1,表明这128个页目录项所指的是128个4M页。这128项所对应的虚拟地址空间 0x80000000 - 0x9FFFFFFF,大小0x20000000 Bytes = 512 M Bytes。<br> 对于 x86 CPU 来说,要支持同时处理4K页目录项和4M页目录项,需要 寄存器CR4中的PSE标志为1,寄存器CR4的第4位是PSE标志。观察Win2k发现寄存器CR4中的PSE标志值为1,表明了Win2k的可以同时混用4M页和4K页。<br> kd> r cr4<br> r cr4<br> cr4=000002d1<br> 对于4M的页目录项来说,它的第22bit到第31bit,这高10bit指明一个4M页的物理地址,第12bit到第21bit这10bit必须为0。最低12bit仍然是那些标志。对于4K的页目录项,它所指的物理页中放着一个页表。而对于4M的页目录项,它所指的物理页是直接用来放代码和数据的。也就是说该项不再需要页表了。CPU进行虚拟地址到物理地址的转换时,使用高10bit作为在页目录中的索引,找到页目录项,发现页目录项的 Large Page 标志位被设置的话,就直接取出该项中的物理地址,然后用虚拟地址的低22bit作为页内偏移,得到物理地址。<br> 系统的核心模组一般比较大,而系统的核心模组会经常使用,所以他们的页表项放在TLB(Translation Look-Aside Buffer)高速缓存中比较好,如果使用4K页,需要多个4K页,也就需要占用比较多的TLB高速缓存。TLB高速缓存是非常宝贵的资源,如果使用4M页的话,那么就可以节省很多TLB高速缓存。<br> 实际中Win2k的两个最重要的核心模组 hal.dll 和 ntoskrnl.exe 被放在这片4M页的地址空间中。<br> 观察这128个页目录项中的物理地址,就会发现 地址空间 80000000 - 9FFFFFFF 将和物理内存 00000000 - 1FFFFFFF 一一映射。比如我有128M物理内存,他们将全部映射在这个地址空间中。从有效标志位来看,这128个页目录项,都是有效的。而且实际上他们总是有效的。他们对应512M的地址空间。如果只有128M的物理内存的话,明显很大一部分实际上不会有物理内存映射的。没有物理内存映射,而页目录项指示有效,那么读这些地址的内存,将会怎样?结果是不会蓝屏,读会成功完成,读出来的所有内容都是FF。<br> 如果这128个页目录项不是4M的页目录项,而是4K的页目录项的话,将会对应128个页表。那么现在这128个页表,从C0200000开始的128个页表,也就是 C0200000 - C027FFFF 这 512K 的地址空间是什么内容呢?观察结果是他们这128页中,映射了和128个页目录项对应4M地址空间的第一个4K相同的内容。比如,地址C0200000的这4K和地址80000000的4K内容是一样的,都是物理地址为00000000的4K。地址C0201000的这4K和地址80400000的4K内容是一样的,都是物理地址为00400000的4K。<br> 关于80000000-9FFFFFFF 将和物理内存 00000000-1FFFFFFF 一一映射。而且这128个页目录项总是有效的。<br> 我们也可以在 ntoskrnl!MmGetPhysicalAddress 函数中找到证据。MmGetPhysicalAddress,将指定的虚拟地址转换成物理地址,参数介绍可以看ddk。这是个很简单的函数,用SoftICE在这个函数上下断点,然后自己写个驱动程序,用不同范围的虚拟地址触发这个函数。用SoftICE跟一遍这个函数的执行过程。就会发现对于在80000000-9FFFFFFF 中的地址,根本没做有效性检查,说明了他们总是有效的。而虚拟地址到物理地址的转换方法说明了和物理内存 00000000-1FFFFFFF 一一映射。其实计算在这个范围之内的虚拟地址对应的物理地址,只需要用虚拟地址减去0x80000000。<br> 下面是使用 kd 反汇编函数 MmGetPhysicalAddress 得到的输出<br> u MmGetPhysicalAddress l 30<br> ntoskrnl!MmGetPhysicalAddress:<br> 804374e0 56 push esi<br> 804374e1 8b742408 mov esi,[esp+0x8]<br> 804374e5 33d2 xor edx,edx<br> 804374e7 81fe00000080 cmp esi,0x80000000<br> 804374ed 722c jb ntoskrnl!MmGetPhysicalAddress+0x2b (8043751b)<br> 804374ef 81fe000000a0 cmp esi,0xa0000000<br> 804374f5 7324 jnb ntoskrnl!MmGetPhysicalAddress+0x2b (8043751b)<br> 804374f7 39153ce74780 cmp [ntoskrnl!MmKseg2Frame (8047e73c)],edx<br> 804374fd 741c jz ntoskrnl!MmGetPhysicalAddress+0x2b (8043751b)<br> 804374ff 8bc6 mov eax,esi<br> 80437501 c1e80c shr eax,0xc<br> 80437504 25ffff0100 and eax,0x1ffff<br> 80437509 6a0c push 0xc<br> 8043750b 59 pop ecx<br> 8043750c e8d3a7fcff call ntoskrnl!_allshl (80401ce4)<br> 80437511 81e6ff0f0000 and esi,0xfff<br> 80437517 03c6 add eax,esi<br> 80437519 eb17 jmp ntoskrnl!MmGetPhysicalAddress+0x57 (80437532)<br> 8043751b 8bc6 mov eax,esi<br> 8043751d c1e80a shr eax,0xa<br> 80437520 25fcff3f00 and eax,0x3ffffc<br> 80437525 2d00000040 sub eax,0x40000000<br> 8043752a 8b00 mov eax,[eax]<br> 8043752c a801 test al,0x1<br> 8043752e 7506 jnz ntoskrnl!MmGetPhysicalAddress+0x44 (80437536)<br> 80437530 33c0 xor eax,eax<br> 80437532 5e pop esi<br> 80437533 c20400 ret 0x4<br> 80437536 c1e80c shr eax,0xc<br> 80437539 ebce jmp ntoskrnl!MmGetPhysicalAddress+0x47 (80437509)<br> 8043753b cc int 3<br> 8种转换<br> 由于页表被映射到了0xc0000000 开始的4MB地址空间。<br> 所以我们也可以象CPU那样完成虚拟地址到物理地址的转换。<br> 系统按照对应虚拟空间的先后顺序,把一个进程的页表映射在0xc0000000 开始的4MB地址空间中,把页目录映射在0xc0300000 开始的4KB地址空间中。于是我们可以做如下几种地址的相互转换。<br> 1 虚拟地址->虚拟地址对应的PDE地址<br> PDE_Address=(VirtualAddress>>22)*4+0xC0300000 <br> 2 虚拟地址->虚拟地址对应的PTE地址<br> PTE_Address=(VirtualAddress>>12)*4+0xC0000000 <br> 3 虚拟地址->物理地址<br> 如果 虚拟地址大于等于0x80000000 并且小于0xa0000000(在 Large Page 部分),<br> 直接用虚拟地址减去0x80000000就得到了物理地址。<br> 其他情况<br> 取得该虚拟地址的PDE,判断是否有效。<br> 有效的话,取得该虚拟地址的PTE,判断是否有效。<br> 有效的话,将PTE的低12位清0加上虚拟地址的低12位就得到了物理地址。<br> 由于页表和页目录在系统地址空间中,访问需要程序运行在ring0,所以要测试的话,需要写驱动程序。<br> unsigned int PDE;<br> unsigned int PTE;<br> if(VirtualAddress>=0x80000000 && VirtualAddress<0xa0000000)<br> {<br> PhysicalAddress=VirtualAddress-0x80000000;<br> }<br> else<br> {<br> PDE=*(unsigned int*)((VirtualAddress>>22)*4+0xC0300000);<br> if(PDE&0x00000001)<br> {<br> PTE=*(unsigned int*)((VirtualAddress>>12)*4+0xC0000000);<br> if(PTE&0x00000001)<br> {<br> PhysicalAddress=((PTE&0xFFFFF000)+(VirtualAddress&0x00000FFF));<br> }<br> }<br> }<br> 4 一个PDE的地址->相应的虚拟地址范围<br> VirtualAddressStart=((PDE_Address-0xC0300000)/4)<<22<br> VirtualAddressEnd=VirtualAddressStart+0x003FFFFF<br> 5 一个PTE的地址->相应的虚拟地址范围<br> VirtualAddressStart=((PTE_Address-0xC0000000)/4)<<12<br> VirtualAddressEnd=VirtualAddressStart+0x00000FFF<br> 6 物理地址->虚拟地址<br> 一个物理地址常常会对应多个虚拟地址。转换方法就是遍历所有页表和页目录,如果有效就比较该项的高20bit是否等于我们提供的物理地址的高20bit,如果相等,就找到了一个。比如该项是第i个PDE的,第j个PTE,那么虚拟地址等于,i*4M+j*4K+物理地址的低12bit。遍历所有页表和页目录找到每一个。<br> 7 一个PTE的地址->相应PDE的地址<br> 一个PTE的地址可以找到相应的虚拟地址范围,就可以找到虚拟地址对应的PDE地址<br> PDE_Address=(VirtualAddress>>22)*4+0xC0300000 <br> PDE_Address=((((PTE_Address-0xC0000000)/4)<<12)>>22)*4+0xC0300000 <br> 8 一个PDE的地址->相应PTE的地址范围<br> 一个PDE的地址可以找到相应的虚拟地址范围的开始地址,就可以找到该虚拟地址对应的PTE地址,<br> 一个PDE对应1024个PTE,4K大小。<br> PTE_AddressStart=(VirtualAddress>>12)*4+0xC0000000<br> PTE_AddressStart=((((PDE_Address-0xC0300000)/4)<<22)>>12)*4+0xC0000000 <br> PTE_AddressEnd=PTE_AddressStart+0x00000FFF<br> 无效页与 Page Fault<br> 访问的虚拟地址所在页在物理内存中时,该虚拟地址所在页相应的 PDE,PTE 都有效,CPU 自动根据相应的PDE,PTE把虚拟地址转换成物理地址,完成访问。一个虚拟地址所在页不在物理内存中时,比如在硬盘上的交换文件中,该虚拟地址所在页相应的 PDE,PTE 都无效,访问该虚拟地址将引起 Page-Fault 异常(Exception)。从而使 CPU 转去执行异常处理程序,异常处理程序会做相应的处理。对于发现访问的虚拟地址所在的页在硬盘上的交换文件中,就从交换文件中读入该页到物理内存,重新使PTE有效,并指向正确的物理页。最后 CPU 重新执行引起异常的指令,这时该指令所访问的虚拟地址已经在物理内存中了,并且该虚拟地址的PTE也有效了,于是就可以顺利执行。<br> 下面我们针对 x86 CPU 做更详细的说明。<br> 当某条指令访问无效页时,比如指令 MOV EAX,InValidAddress ,执行这条指令时,CPU 会自动通过页目录和页表把虚拟地址 InValidAddress 转换成物理地址,在地址转换过程中,CPU 在从页表项得到物理页地址的同时,会进行页保护检查,比如看该页表项是否有效,是否是只读等等。当CPU发现指令中地址的页表项无效,就会引发异常(Exception)。异常也是由 CPU 实现的。这里引起的是一个 Page Fault 异常,它的中断号是 0xe (十进制14),需要注意的是 Page Fault 的中断号是 0xe 这是由 CPU 定义的( x86 CPU 的 从 0 - 31 这32个中断是由 CPU 定义的,CPU 将根据这个定义做相应工作)。在发生异常时,CPU 自动把一些寄存器压入堆栈,然后根据中断号,(通过IDTR寄存器找到中断描述符表)在中断描述符表中找到相应的中断描述符,根据中断描述符中的地址,转到异常处理程序。中断描述符是由Win2k设置,异常处理程序也是由Win2k决定。对于 Win2k Build 2195 来说,中断 0xe 的处理程序是 ntoskrnl!KiTrap0E 地址在 804648a4 。当转到KiTrap0E 时,CPU 已经在堆栈中压入了下面的内容<br> |-------------| <br> | EFLAGS |<br> |-------------|<br> | CS |<br> |-------------|<br> | EIP |<br> |-------------|<br> | Error Code |<br> |-------------|<---- [ ESP ]<br> page-fault 异常 (#PF) 的 Error Code 定义如下( CPU 定义 )<br> | 3 | 2 | 1 | 0 |<br> +---------------------------------------------------+ <br> | Reserved |RSVD|U/S|R/W| P |<br> +---------------------------------------------------+ <br> P 0 错误由无效页引起<br> 1 错误由违反页保护引起<br> W/R 0 引起错误的内存访问是读<br> 1 引起错误的内存访问是写<br> U/S 0 访问错误时处理器处在管理模式<br> 1 访问错误时处理器处在用户模式<br> 需要说明的是堆栈中压入的 EIP 就是引发异常的指令地址,将来将根据这个地址重新执行该指令。而寄存器 cr2 中是引发异常时访问的地址。<br> #PF异常处理程序 KiTrap0E(由Win2k提供)将会调用 ntoskrnl!MmAccessFault ,MmAccessFault 通过 CR2 中的访问地址,计算出相应的 PDE,PTE地址,通过分析PTE中的内容,可以知道是哪种情况引起的异常,并根据情况作出相应的处理。<br> 当发生异常时,CPU会把一些寄存器压入堆栈,转到相应的异常处理程序(由Win2k提供),Win2k 在异常处理程序中又会把一些寄存器压入堆栈,最后会在堆栈中形成一个 KTRAP_FRAME 结构。这个 KTRAP_FRAME 是 ntoskrnl!MmAccessFault 的参数之一。<br> !strct KTRAP_FRAME<br> struct _KTRAP_FRAME (sizeof=140)<br> +00 uint32 DbgEbp<br> +04 uint32 DbgEip<br> +08 uint32 DbgArgMark<br> +0c uint32 DbgArgPointer<br> +10 uint32 TempSegCs<br> +14 uint32 TempEsp<br> +18 uint32 Dr0<br> +1c uint32 Dr1<br> +20 uint32 Dr2<br> +24 uint32 Dr3<br> +28 uint32 Dr6<br> +2c uint32 Dr7<br> +30 uint32 SegGs<br> +34 uint32 SegEs<br> +38 uint32 SegDs<br> +3c uint32 Edx<br> +40 uint32 Ecx<br> +44 uint32 Eax<br> +48 uint32 PreviousPreviousMode<br> +4c struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList<br> +50 uint32 SegFs<br> +54 uint32 Edi<br> +58 uint32 Esi<br> +5c uint32 Ebx<br> +60 uint32 Ebp<br> +64 uint32 ErrCode<br> +68 uint32 Eip<br> +6c uint32 SegCs<br> +70 uint32 EFlags<br> +74 uint32 HardwareEsp<br> +78 uint32 HardwareSegSs<br> +7c uint32 V86Es<br> +80 uint32 V86Ds<br> +84 uint32 V86Fs<br> +88 uint32 V86Gs<br> 系统,CPU 与 页目录项,页表项的关系<br> 一个进程的PDE(页目录项),PTE(页表项)是由系统维护的。地址转换由CPU自动完成。访问无效地址CPU 将产生异常,执行异常处理程序。异常处理程序是系统提供的。<br> 对于有效的 PDE,PTE,他们的格式大部分由CPU定义,CPU 将按照这个格式,根据每一位的值,决定相应的处理方式。CPU 利用这个格式中自己定义的物理页物理地址的部分来进行地址转换,自己定义的一些标志位来实现页的保护。系统必须按照这个格式定义,来维护 PDE 和 PTE。<br> x86 CPU 的有效页表项,CPU 定义如下<br> struct _HARDWARE_PTE_X86 (sizeof=4)<br> bits0-0 Valid<br> bits1-1 Write<br> bits2-2 Owner<br> bits3-3 WriteThrough<br> bits4-4 CacheDisable<br> bits5-5 Accessed<br> bits6-6 Dirty<br> bits7-7 LargePage<br> bits8-8 Global<br> bits9-11 reserved<br> bits12-31 PageFrameNumber<br> 其中要注意的是 bits9-11 reserved 这3位,CPU 没有定义,留给操作系统使用。<br> 对于无效的 PDE,PTE,他们的格式大部分由系统定义。当 CPU 发现访问的 PDE,PTE 无效时,就会转去执行异常处理程序。异常处理程序是由系统提供的。系统将按照自己定义的格式,根据每一位的值,决定相应的处理方式。<br> x86 CPU 的无效页表项,CPU 定义如下<br> struct _HARDWARE_PTE_X86 (sizeof=4)<br> bits0-0 Valid<br> bits1-31 reserved<br> 对于无效页来说,CPU只定义了bits0-0,用来判断是否有效。无效页的 bits0-0 值为0。其他位都留给操作系统使用。 <br> 为什么地址空间的大小是4G <br> 使用32bit的cpu话,处理32bit的数据比较好。这就决定了在代码中将被非常频繁使用的地址是32bit的。而32bit的地址可以寻址的范围是从0x00000000 到 0xFFFFFFFF ,也就是4GB(对于以字节为单位的编址)大小的范围。也就决定了地址空间的大小是 4G。<br> 为什么一页的大小是4K(只是我个人的看法)<br> 确定了虚拟地址空间的大小之后,又决定使用分页来进行内存管理。权衡把虚拟地址转换成物理地址的效率和保存分页信息所用的代价之后,决定了使用页目录和页表2层转换。而使用2层转换最公平的方式就是页目录中的项数和页表中的项数都一样。由于所要保存足够的信息,又由于是32bit cpu 所以,一个PTE或者一个PDE的大小是4个字节也是有理由的。当这些确定了之后,也就确定了一页的大小。<br> 设一页大小是 x ,单位是字节。那么这样一页中有 (x/4) 个PTE或者PDE。一个PTE可以对应一页的地址空间,也就是大小为x个字节的地址空间,一个 Page Table 页中有(x/4) 个PTE,所以一个 Page Table 页可以对应(x/4)*x个字节的地址空间。一个PDE可以找到一个 Page Table 页,也就是大小为(x/4)*x个字节的地址空间,一个 Page Directory 页中有 (x/4) 个PDE,所以一个 Page Directory 页可以对应 (x/4)(x/4)*x 个字节的地址空间。现在需要用一个PDE页对应整个地址空间,整个地址空间是4G字节,也就是4*1024*1024*1024 个字节。所以 (x/4)(x/4)*x=4*1024*1024*1024 可以算出 x = 4*1024 字节,也就是 4k 字节。<br> 地址转换的性能<br> 一旦使用了分页(CPU的相关寄存器的分页标志位被设置),所有的内存操作都使用的是虚拟地址,CPU会自动转换成物理地址,可以想象将会有非常大量的地址转换,一次转换可能需要读页目录表,读页表,最后才在页中读写数据。所以有理由把一些页目录项和页表项放入高速缓存中来提高地址转换的速度。实际中也是这样做的,对于 x86 cpu ,如果启用了分页,cpu 会使用一个叫做 TLB(Translation Look-Aside Buffer) 的高速缓存来存储经常被用到的页目录和页表项。<br> 页目录的地址为什么是C0300000,1个页目录加上1024个页表为什么只使用了1024*4K的地址空间<br> 对于要映射整个4G地址空间,是需要1024个页表和1个页目录的,每个都是4KB大小,也就是 1024*4KB+1*4KB=4MB+4KB。而实际中Win2k把每个进程的页目录和页表映射到了从 0xC0000000到0xC03FFFFF 这4MB的地址空间中(页目录在0xC0300000开始的4K)。注意是4MB地址空间而不是4MB+4KB。1024个页表和1个页目录,应该是需要(1024+1)*4KB的地址空间的。而现在Win2k只使用了1024*4KB的地址空间这是为什么?<br> 原因就是页表被映射到了进程的地址空间。<br> 如果页表和页目录没有被映射到进程的地址空间中,而一个进程的4GB地址空间又都映射了物理内存的话,那么就确实需要1024个物理页来存放页表,和另外1个物理页来存放页目录,也就是需要(1024+1)*4KB的物理内存。<br> 但是页表被映射到了进程的地址空间中,这导致了一个页表的内容和页目录的内容是完全一样的,正是这种完全相同,使得将1024个页表加1个页目录映射到地址空间只需要1024*4KB的地址空间,其中的一个页表和页目录完全重合了。<br> 一个页表1024项,每项对应4KB地址空间,一个页表对应4MB的地址空间。1024个对应了整个4GB地址空间。1024个页表也被映射到了从 0xC0000000到0xC03FFFFF 的4MB地址空间中。这4MB地址空间也是由一个页表来对应的。我们来看对应于从 0xC0000000到0xC03FFFFF 这4MB的地址空间的页表。该页表有1024项,每项对应一页的地址空间,表明是否在物理内存中,如果在,物理地址是多少。而这个页表是对应页表所在的4MB地址空间的,所以它的每一项对应的一页,正是每个页表所在的页。也就是说这个页表的每一项指出了一个页表是否有物理内存映射,如果有的话,物理地址是多少。这正是页目录所做的工作。把1024个页表映射到了地址空间,导致了1024个页表中的一个的内容和页目录完全重合,它既是页目录又是页表。所以1个页目录加上1024个页表只使用了1024*4K的地址空间。<br> 页表被映射到地址空间的什么地方,是由操作系统的设计者决定的,他会综合考虑各种问题,作出最后的决定。不过一旦页表所在的地址空间的地址决定了,那么页目录的地址也就决定了,除非他打算多使用一页的地址空间保存和现在一个页表中完全相同的内容。<br> Win2k中把页表映射到了从 0xC0000000到0xC03FFFFF 的4MB地址空间中,我们来计算一下负责这4M地址空间的那个页表的地址,那个页表就是和页目录重合的页表。4MB地址空间的首地址0xC0000000显然是由该页表的第一项负责的,我们用这个地址来计算。PTE_Address=(VirtualAddress>>12)*4+0xC0000000,<br> (0xC0000000>>12)*4+0xC0000000=0xC0000*4+0xC0000000=0x300000+0xC0000000=0xC0300000<br> 正是页目录的虚拟地址。<br> 0xC0300000到0xC0300FFF这4KB的地址空间,作为普通一页的话由一个PTE指明所在物理页的物理地址,作为一个页表所在页的话由一个PDE指明所在物理页的物理地址,作为页目录的话由CR3指明所在物理页的物理地址。<br> 0xC0300000到0xC0300FFF这4KB作为普通的一页是由哪个PTE对应呢,PTE_Address=(VirtualAddress>>12)*4+0xC0000000,计算得到0xC0300C00。也就是说0xC0300C00处的4个字节作为PTE,指明了0xC0300000到0xC0300FFF这4KB所在的物理页的物理地址。<br> 0xC0300000到0xC0300FFF这4KB作为一个页表所在页是由哪个PDE对应呢,PDE_Address=(VirtualAddress>>22)*4+0xC0300000,计算得到0xC0300C00。也就是说0xC0300C00处的4个字节作为PDE,指明了0xC0300000到0xC0300FFF这4KB所在的物理页的物理地址。<br> 0xC0300000到0xC0300FFF这4KB作为页目录的话,由 CR3 指明所在物理页的物理地址。所以 0xC0300C00 处的4个字节的值,把标志位清0的话,就等于 CR3 中的值。<br> 下面这个特殊地址的转换过程,你就会发现页目录和一个页表确实是重合了,而且它既是页目录又是页表。<br> 虚拟地址 C0300C00 转换成物理地址,以下输出来自 kd。<br> kd> r cr3<br> r cr3<br> cr3=069ca000<br> // CPU第一步根据cr3里的物理地址找到页目录所在物理页<br> // 取C0300000的最高10bit, 1100 0000 00 = 11 0000 0000 = 300 ,作为页目录项索引,由于每项长4字节<br> // 所以页目录项的物理地址为 300*4+069ca000=069cac00<br> kd> !dd 069cac00<br> !dd 069cac00<br> # 69cac00 069ca063 01e2b063 00000000 01670163<br> # 69cac10 01671163 01672163 01673163 01674163<br> # 69cac20 01675163 01676163 01657163 01658163<br> # 69cac30 01659163 0165a163 0165b163 0165c163<br> # 69cac40 0165d163 0165e163 0165f163 016c0163<br> # 69cac50 01681163 01682163 01683163 01684163<br> # 69cac60 01685163 01686163 01687163 01688163<br> # 69cac70 01689163 0168a163 0168b163 0168c163<br> // 结果该页目录项中的物理地址(页目录项的高20bit是物理页帧号,低12bit是标志)是069ca000<br> // 注意页表的物理地址等于页目录的物理地址,说明了页目录和页表是重合的。<br> // CPU第二步根据该目录项中的物理地址找到页表所在的物理页<br> // 取C0300000的最高10bit之后的10bit, 11 0000 0000 = 300 ,作为页表项索引,由于每项长4字节<br> // 所以页表项的物理地址为 300*4+069ca000=069cac00<br> kd> !dd 069cac00<br> !dd 069cac00<br> # 69cac00 069ca063 01e2b063 00000000 01670163<br> # 69cac10 01671163 01672163 01673163 01674163<br> # 69cac20 01675163 01676163 01657163 01658163<br> # 69cac30 01659163 0165a163 0165b163 0165c163<br> # 69cac40 0165d163 0165e163 0165f163 016c0163<br> # 69cac50 01681163 01682163 01683163 01684163<br> # 69cac60 01685163 01686163 01687163 01688163<br> # 69cac70 01689163 0168a163 0168b163 0168c163<br> // 结果该页表项中的物理地址(页目录项的高20bit是物理页帧号,低12bit是标志)是069ca000<br> // CPU第三步根据页表项中的物理地址找到物理页,用C0300000低12bit作为页内偏移,<br> // 相加得到物理地址 ,低12bit, 1100 0000 0000 =c00,c00+069ca000=069cac00<br> // 这样就得到了虚拟地址 C0300C00 对应的物理地址 069cac00<br> kd> !dd 069cac00<br> !dd 069cac00<br> # 69cac00 069ca063 01e2b063 00000000 01670163<br> # 69cac10 01671163 01672163 01673163 01674163<br> # 69cac20 01675163 01676163 01657163 01658163<br> # 69cac30 01659163 0165a163 0165b163 0165c163<br> # 69cac40 0165d163 0165e163 0165f163 016c0163<br> # 69cac50 01681163 01682163 01683163 01684163<br> # 69cac60 01685163 01686163 01687163 01688163<br> # 69cac70 01689163 0168a163 0168b163 0168c163<br> // 该处的DWORD值为 069ca063<br> // 前面看到 CR3 的值为 069ca000<br> 一个进程的页目录和页表本身所需要的物理内存<br> 一个进程需要物理页来放页表和页目录,如果有1024个页表,那么不是需要1024*4K=4M 的物理内存吗?一个进程只是页表信息就需要4M 的物理内存吗?不过实际上,当页目录中的一项有效标志位(第0位,最低位)为0,那么该项对应的页表就不存在,就不需要占用一个物理页。在前面的页目录的例子中我们已经看到了用户地址空间中有多少个无效项(系统地址空间中的东西,基本上大家都一样)。也就是说实际上为了保存一个进程的页表用不了多少物理内存。<br> 这也就是为什么要使用2级的地址转换。如果只使用一级,只用页表,那么每个进程1024个页表就必须都放在物理内存中,即每个进程需要4M物理内存来放页表,这个代价对目前来说是太大了。使用2级地址转换,多一个步骤,虽然转换速度会变慢一些,但是节省了物理内存,在速度与内存之间寻求了平衡。<br> 页目录项的 Write 标志位<br> 从前面页目录的例子中,可以看到页目录的标志 bits1-1 Write ,总是为1。<br> 表明页表所在的物理页总是可写的。这是因为页表和页目录是由系统维护的,系统需要向其中写入东西。<br> 保护模式,Flat Model,线性地址,逻辑地址,ring0,ring3<br> 以下内容只针对x86<br> Win2k 运行在保护模式(Protected Mode )下,是否运行在保护模式下,取决于PE(Protection Enable)标志位 (CR0 的 bit 0 )。为0表示实模式(Real-Address Mode)(当机器加电启动和重启的时候,x86 CPU 处于实模式下),为1表示保护模式。观察Win2k的CR0的bit0,值为1,表明运行在保护模式下。<br> 对于x86体系结构来说,分段机制是必须被使用的(分页机制是可选的,分段和分页可以同时使用,Win2k使用了分页机制)。比如CPU执行代码总是参考代码段。在保护模式下,段寄存器(CS,DS,SS,ES,FS,GS)中放着的是段选择符,用于在某个描述符表中寻找段描述符。<br> 保护模式下的分段机制,有多种使用模型,Win2k使用的是一种叫做 Flat Model (平坦模型)。就是通过把段基址设为0,段界限设为4G,这样每个段都是整个地址空间,这样就隐藏了分段机制。<br> 全局描述符表<br> 全局描述符表(GDT,global descriptor table)用来存放描述符,整个系统只有一个。由GDTR(全局描述符表寄存器)指出所在位置和大小。由于GDTR中的界限部分为16位,所以全局描述符表最大可以为64KB,每个描述符占8个字节,所以全局描述符表中最多可以放8192个描述符。<br> 段选择符(CS,DS,SS,ES,FS,GS中放的是段选择符)的格式定义如下(来自Intel手册):<br> 段选择符,长2个字节,16bit。<br> Index: bit3-bit15 13位 在全局描述符表或者局部描述符表中的索引,可以索引8192个描述符<br> TI flag: bit2 1位 TI,table indicator,指定描述符表。为0在全局描述符表(GDT)中选择,为1在 当前的局部描述符表(LDT)中选择<br> RPL: bit0-bit1 2位 选择符的特权级<br> 全局描述符表寄存器(GDTR,48bit)格式定义如下(来自Intel手册):<br> Table Limit: bit0-bit15 16位 指定描述符表的字节数。<br> Base Address: bit16-bit47 32位 指定描述符表的基地址。是线性地址。<br> 段描述符格式定义如下:<br> typedef struct _SEG_DESCRIPTOR //size 8 bytes<br> {<br> unsigned short limit_0_15;<br> unsigned short base_0_15;<br> unsigned char base_16_23;<br> unsigned char accessed : 1;<br> unsigned char r_w_e : 1;<br> unsigned char e_c : 1;<br> unsigned char code_data : 1;<br> unsigned char app_system : 1;<br> unsigned char dpl : 2;<br> unsigned char present : 1;<br> unsigned char limit_16_19 : 4;<br> unsigned char unused : 1;<br> unsigned char always_0 : 1;<br> unsigned char seg_16_32 : 1;<br> unsigned char granularity : 1;<br> unsigned char base_24_31;<br> } SEG_DESCRIPTOR ,*PSEG_DESCRIPTOR;<br> limit_0_15,limit_16_19,granularity<br> 段界限,两部分,共20bit。<br> 如果granularity位为0,段界限的值以字节为单位。段最大为1MB。<br> 如果granularity位为1,段界限的值以4KB为单位。段最大为4GB。<br> base_0_15,base_16_23,base_24_31<br> 段基址,三部分,共32bit。<br> accessed,readable,conforming,code_data<br> accessed表示是否已经被访问过了。<br> code_data为0表示代码段,为1表示数据段。<br> 对于数据段,r_w_e位表示是否可写,为0只读,为1可写。e_c位表示增长方向,为1向下增长。<br> 对于代码段,r_w_e位表示是否可读,为0只执行,为1可读。e_c位表示conforming或者nonconforming。<br> app_system<br> 0 = system, 1 = code or data。为1时,表明是代码段或者数据段。为0时表明是系统段,系统段一些位的含义和数据段或者代码段不同。有以下几种系统段:16-Bit TSS (Available),LDT,16-Bit TSS (Busy),16-Bit Call Gate,Task Gate,16-Bit Interrupt Gate,16-Bit Trap Gate,32-Bit TSS (Available),32-Bit TSS (Busy),32-Bit Call Gate,32-Bit Interrupt Gate,32-Bit Trap Gate。更多内容可以参考 Intel 手册。<br> dpl<br> 指定段的特权级。<br> present<br> 段是否在内存中<br> seg_16_32<br> 段是16位还是32位。<br> 下面看Win2k中实际的用法<br> 一个ring3程序的段寄存器<br> (使用VC调试器获得,也可以自己写程序获得,也可以用SoftICE断到一个ring3程序中获得...)<br> CS = 001B DS = 0023 ES = 0023 SS = 0023 FS = 0038 GS = 0000<br> 一个ring0程序的段寄存器<br> (使用KD获得,也可以写驱动程序获得,也可以用SoftICE断到一个ring0程序中获得...)<br> cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000<br> GDTR的内容可以由指令sgdt得到(sgdt不是特权指令,ring3也可以执行)。<br> 下面的内容来自SoftICE:<br> :gdt<br> Sel. Type Base Limit DPL Attributes<br> GDTbase=80036000 Limit=03FF<br> // GDTbase=80036000 Limit=03FF ,可以使用 sgdt指令做验证<br> // 16bit的界限值为03FF,表明Win2k中GDT只有1K,可以存放128个描述符<br> 0008 Code32 00000000 FFFFFFFF 0 P RE<br> 0010 Data32 00000000 FFFFFFFF 0 P RW<br> 001B Code32 00000000 FFFFFFFF 3 P RE<br> 0023 Data32 00000000 FFFFFFFF 3 P RW<br> 0028 TSS32 801F4000 000020AB 0 P B<br> 0030 Data32 FFDFF000 00001FFF 0 P RW<br> 003B Data32 00000000 00000FFF 3 P RW<br> 0043 Data16 00000400 0000FFFF 3 P RW<br> 0048 Reserved 00000000 00000000 0 NP<br> 0050 TSS32 80470040 00000068 0 P<br> 0058 TSS32 804700A8 00000068 0 P<br> 0060 Data16 00022AB0 0000FFFF 0 P RW<br> 0068 Data16 000B8000 00003FFF 0 P RW<br> 0070 Data16 FFFF7000 000003FF 0 P RW<br> 0078 Code16 80400000 0000FFFF 0 P RE<br> 0080 Data16 80400000 0000FFFF 0 P RW<br> 0088 Data16 00000000 00000000 0 P RW<br> 0090 Reserved 00000000 00000000 0 NP<br> 0098 Reserved 00000000 00000000 0 NP<br> 00A0 TSS32 8141A348 00000068 0 P<br> 00A8 Reserved 00000000 00000000 0 NP<br> 00B0 Reserved 00000000 00000000 0 NP<br> 00B8 Reserved 00000000 00000000 0 NP<br> 00C0 Reserved 00000000 00000000 0 NP<br> 00C8 Reserved 00000000 00000000 0 NP<br> 00D0 Reserved 00000000 00000000 0 NP<br> 00D8 Reserved 00000000 00000000 0 NP<br> 00E0 Code16 F0450000 0000FFFF 0 P RE ED<br> 00E8 Data16 00000000 0000FFFF 0 P RW<br> 00F0 Code16 8042DCE8 000003B7 0 P EO<br> 00F8 Data16 00000000 0000FFFF 0 P RW<br> 0100 Data32 F0460000 0000FFFF 0 P RW<br> 0108 Data32 F0460000 0000FFFF 0 P RW<br> 0110 Data32 F0460000 0000FFFF 0 P RW<br> 0118 Reserved 00008003 00006120 0 NP<br> 0120 Reserved 00008003 00006128 0 NP<br> 0128 Reserved 00008003 00006130 0 NP<br> 0130 Reserved 00008003 00006138 0 NP<br> 0138 Reserved 00008003 00006140 0 NP<br> 0140 Reserved 00008003 00006148 0 NP<br> 0148 Reserved 00008003 00006150 0 NP<br> 0150 Reserved 00008003 00006158 0 NP<br> 0158 Reserved 00008003 00006160 0 NP<br> 0160 Reserved 00008003 00006168 0 NP<br> 0168 Reserved 00008003 00006170 0 NP<br> 0170 Reserved 00008003 00006178 0 NP<br> 0178 Reserved 00008003 00006180 0 NP<br> 0180 Reserved 00008003 00006188 0 NP<br> 0188 Reserved 00008003 00006190 0 NP<br> 0190 Reserved 00008003 00006198 0 NP<br> 0198 Reserved 00008003 000061A0 0 NP<br> 01A0 Reserved 00008003 000061A8 0 NP<br> 01A8 Reserved 00008003 000061B0 0 NP<br> 01B0 Reserved 00008003 000061B8 0 NP<br> 01B8 Reserved 00008003 000061C0 0 NP<br> 01C0 Reserved 00008003 000061C8 0 NP<br> 01C8 Reserved 00008003 000061D0 0 NP<br> 01D0 Reserved 00008003 000061D8 0 NP<br> 01D8 Reserved 00008003 000061E0 0 NP<br> 01E0 Reserved 00008003 000061E8 0 NP<br> 01E8 Reserved 00008003 000061F0 0 NP<br> 01F0 Reserved 00008003 000061F8 0 NP<br> 01F8 Reserved 00008003 00006200 0 NP<br> 0200 Reserved 00008003 00006208 0 NP<br> 0208 Reserved 00008003 00006210 0 NP<br> 0210 Reserved 00008003 00006218 0 NP<br> 0218 Reserved 00008003 00006220 0 NP<br> 0220 Reserved 00008003 00006228 0 NP<br> 0228 Reserved 00008003 00006230 0 NP<br> 0230 Reserved 00008003 00006238 0 NP<br> 0238 Reserved 00008003 00006240 0 NP<br> 0240 Reserved 00008003 00006248 0 NP<br> 0248 Reserved 00008003 00006250 0 NP<br> 0250 Reserved 00008003 00006258 0 NP<br> 0258 Reserved 00008003 00006260 0 NP<br> 0260 Reserved 00008003 00006268 0 NP<br> 0268 Reserved 00008003 00006270 0 NP<br> 0270 Reserved 00008003 00006278 0 NP<br> 0278 Reserved 00008003 00006280 0 NP<br> 0280 Reserved 00008003 00006288 0 NP<br> 0288 Reserved 00008003 00006290 0 NP<br> 0290 Reserved 00008003 00006298 0 NP<br> 0298 Reserved 00008003 000062A0 0 NP<br> 02A0 Reserved 00008003 000062A8 0 NP<br> 02A8 Reserved 00008003 000062B0 0 NP<br> 02B0 Reserved 00008003 000062B8 0 NP<br> 02B8 Reserved 00008003 000062C0 0 NP<br> 02C0 Reserved 00008003 000062C8 0 NP<br> 02C8 Reserved 00008003 000062D0 0 NP<br> 02D0 Reserved 00008003 000062D8 0 NP<br> 02D8 Reserved 00008003 000062E0 0 NP<br> 02E0 Reserved 00008003 000062E8 0 NP<br> 02E8 Reserved 00008003 000062F0 0 NP<br> 02F0 Reserved 00008003 000062F8 0 NP<br> 02F8 Reserved 00008003 00006300 0 NP<br> 0300 Reserved 00008003 00006308 0 NP<br> 0308 Reserved 00008003 00006310 0 NP<br> 0310 Reserved 00008003 00006318 0 NP<br> 0318 Reserved 00008003 00006320 0 NP<br> 0320 Reserved 00008003 00006328 0 NP<br> 0328 Reserved 00008003 00006330 0 NP<br> 0330 Reserved 00008003 00006338 0 NP<br> 0338 Reserved 00008003 00006340 0 NP<br> 0340 Reserved 00008003 00006348 0 NP<br> 0348 Reserved 00008003 00006350 0 NP<br> 0350 Reserved 00008003 00006358 0 NP<br> 0358 Reserved 00008003 00006360 0 NP<br> 0360 Reserved 00008003 00006368 0 NP<br> 0368 Reserved 00008003 00006370 0 NP<br> 0370 Reserved 00008003 00006378 0 NP<br> 0378 Reserved 00008003 00006380 0 NP<br> 0380 Reserved 00008003 00006388 0 NP<br> 0388 Reserved 00008003 00006390 0 NP<br> 0390 Reserved 00008003 00006398 0 NP<br> 0398 Reserved 00008003 000063A0 0 NP<br> 03A0 Reserved 00008003 000063A8 0 NP<br> 03A8 Reserved 00008003 000063B0 0 NP<br> 03B0 Reserved 00008003 000063B8 0 NP<br> 03B8 Reserved 00008003 000063C0 0 NP<br> 03C0 Reserved 00008003 000063C8 0 NP<br> 03C8 Reserved 00008003 000063D0 0 NP<br> 03D0 Reserved 00008003 000063D8 0 NP<br> 03D8 Reserved 00008003 000063E0 0 NP<br> 03E0 Reserved 00008003 000063E8 0 NP<br> 03E8 Reserved 00008003 000063F0 0 NP<br> 03F0 Reserved 00008003 000063F8 0 NP<br> 03F8 Reserved 00000000 00000000 0 NP<br> :dd 80036000 l 400<br> 0010:80036000 00000000 00000000 0000FFFF 00CF9B00 ................<br> 0010:80036010 0000FFFF 00CF9300 0000FFFF 00CFFB00 ................<br> 0010:80036020 0000FFFF 00CFF300 400020AB 80008B1F ......... .@....<br> 0010:80036030 F0000001 FFC093DF 00000FFF 0040F300 ..............@.<br> 0010:80036040 0400FFFF 0000F200 00000000 00000000 ................<br> 0010:80036050 00400068 80008947 00A80068 80008947 h.@.G...h...G...<br> 0010:80036060 2AB0FFFF 00009302 80003FFF 0000920B ...*.....?......<br> 0010:80036070 700003FF FF0092FF 0000FFFF 80009A40 ...p........@...<br> 0010:80036080 0000FFFF 80009240 00000000 00009200 ....@...........<br> 0010:80036090 00000000 00000000 00000000 00000000 ................<br> 0010:800360A0 A3480068 81008941 00000000 00000000 h.H.A...........<br> 0010:800360B0 00000000 00000000 00000000 00000000 ................<br> 0010:800360C0 00000000 00000000 00000000 00000000 ................<br> 0010:800360D0 00000000 00000000 00000000 00000000 ................<br> 0010:800360E0 0000FFFF F0009F45 0000FFFF 00009200 ....E...........<br> 0010:800360F0 DCE803B7 80009842 0000FFFF 00009200 ....B...........<br> 0010:80036100 0000FFFF F0409346 0000FFFF F0409346 ....F.@.....F.@.<br> 0010:80036110 0000FFFF F0409346 80036120 00000000 ....F.@. a......<br> 0010:80036120 80036128 00000000 80036130 00000000 (a......0a......<br> 0010:80036130 80036138 00000000 80036140 00000000 8a......@a......<br> 0010:80036140 80036148 00000000 80036150 00000000 Ha......Pa......<br> 0010:80036150 80036158 00000000 80036160 00000000 Xa......`a......<br> 0010:80036160 80036168 00000000 80036170 00000000 ha......pa......<br> 0010:80036170 80036178 00000000 80036180 00000000 xa.......a......<br> 0010:80036180 80036188 00000000 80036190 00000000 .a.......a......<br> 0010:80036190 80036198 00000000 800361A0 00000000 .a.......a......<br> 0010:800361A0 800361A8 00000000 800361B0 00000000 .a.......a......<br> 0010:800361B0 800361B8 00000000 800361C0 00000000 .a.......a......<br> 0010:800361C0 800361C8 00000000 800361D0 00000000 .a.......a......<br> 0010:800361D0 800361D8 00000000 800361E0 00000000 .a.......a......<br> 0010:800361E0 800361E8 00000000 800361F0 00000000 .a.......a......<br> 0010:800361F0 800361F8 00000000 80036200 00000000 .a.......b......<br> 0010:80036200 80036208 00000000 80036210 00000000 .b.......b......<br> 0010:80036210 80036218 00000000 80036220 00000000 .b...... b......<br> 0010:80036220 80036228 00000000 80036230 00000000 (b......0b......<br> 0010:80036230 80036238 00000000 80036240 00000000 8b......@b......<br> 0010:80036240 80036248 00000000 80036250 00000000 Hb......Pb......<br> 0010:80036250 80036258 00000000 80036260 00000000 Xb......`b......<br> 0010:80036260 80036268 00000000 80036270 00000000 hb......pb......<br> 0010:80036270 80036278 00000000 80036280 00000000 xb.......b......<br> 0010:80036280 80036288 00000000 80036290 00000000 .b.......b......<br> 0010:80036290 80036298 00000000 800362A0 00000000 .b.......b......<br> 0010:800362A0 800362A8 00000000 800362B0 00000000 .b.......b......<br> 0010:800362B0 800362B8 00000000 800362C0 00000000 .b.......b......<br> 0010:800362C0 800362C8 00000000 800362D0 00000000 .b.......b......<br> 0010:800362D0 800362D8 00000000 800362E0 00000000 .b.......b......<br> 0010:800362E0 800362E8 00000000 800362F0 00000000 .b.......b......<br> 0010:800362F0 800362F8 00000000 80036300 00000000 .b.......c......<br> 0010:80036300 80036308 00000000 80036310 00000000 .c.......c......<br> 0010:80036310 80036318 00000000 80036320 00000000 .c...... c......<br> 0010:80036320 80036328 00000000 80036330 00000000 (c......0c......<br> 0010:80036330 80036338 00000000 80036340 00000000 8c......@c......<br> 0010:80036340 80036348 00000000 80036350 00000000 Hc......Pc......<br> 0010:80036350 80036358 00000000 80036360 00000000 Xc......`c......<br> 0010:80036360 80036368 00000000 80036370 00000000 hc......pc......<br> 0010:80036370 80036378 00000000 80036380 00000000 xc.......c......<br> 0010:80036380 80036388 00000000 80036390 00000000 .c.......c......<br> 0010:80036390 80036398 00000000 800363A0 00000000 .c.......c......<br> 0010:800363A0 800363A8 00000000 800363B0 00000000 .c.......c......<br> 0010:800363B0 800363B8 00000000 800363C0 00000000 .c.......c......<br> 0010:800363C0 800363C8 00000000 800363D0 00000000 .c.......c......<br> 0010:800363D0 800363D8 00000000 800363E0 00000000 .c.......c......<br> 0010:800363E0 800363E8 00000000 800363F0 00000000 .c.......c......<br> 0010:800363F0 800363F8 00000000 00000000 00000000 .c..............<br> 我们来分析一下:<br> 对于ring3,CS=001B DS=0023 ES=0023 SS=0023 FS=0038 GS=0000,<br> DS,ES,SS,指向同一个段。<br> 001B=0000000000011 0 11<br> 0023=0000000000100 0 11<br> 所以根据前面段选择符的定义,表示 CS,DS,ES,SS 都是在全局描述符表中进行选择。<br> 选择符的特权级都是3(ring3)。对于CS,索引为3,由于每个描述符为8个字节,描述符相对于GDT开始处的地址为0x3*0x8=0x18。对于,DS,ES,SS,索引为4,描述符相对于GDT开始处的地址为0x4*0x8=0x20。<br> 根据前面段描述符的定义,分析 80036018 开始的8个字节,和 80036020 开始的8个字节。<br> 0010:80036010 0000FFFF 00CF9300 0000FFFF 00CFFB00 ................<br> 0010:80036020 0000FFFF 00CFF300 400020AB 80008B1F ......... .@....<br> 可以得出<br> Sel. Type Base Limit DPL Attributes<br> 001B Code32 00000000 FFFFFFFF 3 P RE<br> 0023 Data32 00000000 FFFFFFFF 3 P RW<br> 可以看到,CS 对应的全局描述符表中的段描述符,是一个代码段,段基址为0,段界限为4G,DPL为3(ring3)。DS,ES,SS 对应的全局描述符表中的段描述符,是一个数据段,段基址为0,段界限为4G,DPL为3(ring3)。<br> 对于ring0, cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000,<br> 0008=0000000000001 0 00<br> 0010=0000000000010 0 00<br> 0023=0000000000100 0 11<br> Sel. Type Base Limit DPL Attributes<br> 0008 Code32 00000000 FFFFFFFF 0 P RE<br> 0010 Data32 00000000 FFFFFFFF 0 P RW<br> 0023 Data32 00000000 FFFFFFFF 3 P RW<br> 可以看到,代码段和堆栈段的DPL为0(ring0)。三个描述符的段基址都为0,段界限都为4G。<br> CS,DS,ES,SS,这些段都完全重叠了,而且都是当前的4G地址空间。和段的另外一种使用方法(不同的段在不同的一块地址空间)相比,现在的使用方法,整个地址空间是连续的,平坦的,所以叫做平坦模式(Flat Model)。<br> 关于段寄存器(CS,DS,SS,ES,FS,GS),不可能每次参考一个段的时候CPU都去从内存中取出段描述符然后再做相应的处理,每个段寄存器还有看不到的部分,他们中存储着相应的段描述符中的信息。<br> 全局描述表中的第一项不被使用,设为了"null descriptor" 。<br> 0010:80036000 00000000 00000000<br> 用来初始化没有被使用的段寄存器,以防止如果被不小心使用一个没有被使用的段寄存器,对系统造成不良影响。Win2k中,段寄存器GS就没有被使用,值都设为了0。<br> 前面分析了 CS,DS,ES,SS 。对于 GS 来说,我们可以看到它的值总是为0,Win2k 并没有使用它。而对于 FS 来说,对于使用平坦模式的 Win2k 来说,它是一个例外,在其他地方会对 FS 做更多的介绍。<br> 在 ntddk.h 中的以下内容,也说明了上面的一些分析。<br> #define KGDT_NULL 0<br> #define KGDT_R0_CODE 8<br> #define KGDT_R0_DATA 16<br> #define KGDT_R3_CODE 24<br> #define KGDT_R3_DATA 32<br> #define KGDT_TSS 40<br> #define KGDT_R0_PCR 48<br> #define KGDT_R3_TEB 56<br> #define KGDT_VDM_TILE 64<br> #define KGDT_LDT 72<br> #define KGDT_DF_TSS 80<br> #define KGDT_NMI_TSS 88<br> 线性地址(linear address),把32bit可寻址的4G地址空间看做连续的线性地址空间,线性地址空间中的地址叫线性地址。逻辑地址(logical address),逻辑地址由一个段选择符(16位)和一个段内偏移(32位)组成。也经常被叫做远程指针(far pointer)。x86 CPU 总是使用分段机制的(即使是使用了最少的分段机制的平坦模型),因此 x86 CPU 指令中的地址也总是逻辑地址,是相对于某一个段而言的地址。在保护模式下,x86 CPU 首先把逻辑地址转换成线性地址,然后再把线性地址转换成物理地址。<br> 对于Win2k来说,由于使用了平坦模型,虚拟地址XXXXXXXX 和线性地址XXXXXXXX 指的是同一个地方。而平坦模型下,CS,DS,SS 这几个段的段基址为0,段界限为4G,就是整个地址空间,所以逻辑地址中的段内偏移的值就等于该逻辑地址转换成线性地址以后的值。<br> 保护模式下的 x86 CPU 有4个特权级,从0到3。被叫做ring0,ring1,ring2,ring3。ring0权限最大,ring3权限最小。对于Win2k来说,只使用了ring0,ring3两个特权级。用户应用程序运行在ring3,系统内核运行在ring0。<br> Win2k中进程的地址空间,被分为用户地址空间和系统地址空间。用户模式下的程序将不能访问系统地址空间,这就是通过保护机制实现的。页目录项和页表项的 bit2 ,Owner标志位表明了访问所需的特权级,为0表示访问需要ring0的特权级,为1表示ring3的特权级就可以访问。在发生内存访问时,CPU会把虚拟地址转换成物理地址。转换过程中,在从页目录项和页表项中获得物理地址的同时,会检查页目录项和页表项中的Owner标志位和当前的特权级,如果没有足够的特权级将会产生一个 page-fault 异常。注意权限的检测和地址的转换是同时由硬件进行的,不会为此损失额外的性能。当前特权级(CPL,Current privilege level),当前执行程序的特权级,由CS,SS段寄存器中的最低2位指明。<br> 保护模式下的 x86 CPU 提供了很多的保护机制,这也就是为什么叫保护模式,更多内容可以参考 Intel手册。<br> 未来 <br> 呃,从某种意义上来说,我认为未来是可以预知的。就像天气预报所作的,在今天就知道明天或者后天将要发生的事情。当然,实际上我认为对于人类来说未来是不可预知的,人类所能知道的事情太有限了。呃,如果要估计我们现在讨论的分页机制还能在内存中活几年,就得估计CPU的发展,可能的新的需求的出现,人们的创造力。挺费事,又没有预测以后一些人痛斥学校的愚昧的情景那么过瘾,所以我要说的未来不是关于分页的。我认为不久的将来人工智能和机器人将非常重要。当然,实际上我认为当有真正的人工智能出现的时候,人类很有可能也就完了。