windows 虚拟内存笔记
2025-08-18

Windows 分页





线性地址通过4层页表变成物理地址,让CPU实际可以访问到物理地址。

也就是说,线性地址其实是由四层页表+偏移组合而成的





线性地址组成

在32位系统下,windows有两种分页机制,2-9-9-12分页以及10-10-12分页,而在64位下只有一种分页机制,那就是9-9-9-9-12分页

在x64体系中,只有48位是用来确定虚拟地址的,前面的16位成为符号拓展位,这16位只有为全1或者为全0两种情况。除了这两种情况之外的地址都是不合法的。

这16位为全1时表示这个地址是一个内核空间的地址,而为全0时表示这个地址是一个用户空间的地址。而在windows操作系统中,由于种种原因,又只用了这48位线性地址中的 44位 。也就是说windows分配的线性地址前20位都是要么为全0,要么为全1


PS位





除了四级页表后的PDPTE PDE 这两个页表都可能拥有PS位

PS为一般在第7位

在PDPTE如果PS位为1 就认为是映射1GB 大页

如果在PDE PS位为1 那么就认为是映射2MB 大页


CR3寄存器

例子
00007ff8`c5810000

011111111

111100011

000101100

000010000

000000000000





CR3是1ad000

第一层应该就是1ad000 + 255(8个1) * 8(每一个PML4E都是寄存器大小 8 字节) = 0x1ad7f8





得到PML4E8A0000000F27C867

在 x64 页表中,PML4E 的高 40 位存储下一级页表(PDPT)的物理基地址,低 12 位为属性标志(如存在位、读写权限等)


名称 值 类型
pdpt 0x8a0000000f27c000 unsigned __int64

得到PDPT基地址 f27c000

然后就是 f27c000+ 1e3 * 8 = f27cf18





0a000000`0f27d867

相同手法获得PDT 基地址 f27d000

000101100 = 0x2c 然后0x2c * 8 = 0x160

PT在f27d160





pt基地址为f27e000 + 0x80 = f27e080





最终结果0xf185000





Amd64VtoP: Virt 00007ff8c5810000, pagedir 00000000001ad000Amd64VtoP: PML4E 00000000001ad7f8Amd64VtoP: PDPE 000000000f27cf18Amd64VtoP: PDE 000000000f27d160Amd64VtoP: PTE 000000000f27e080Amd64VtoP: Mapped phys 000000000f185000Virtual address 7ff8c5810000 translates to physical address f185000.

成功手算出了物理地址


PTE -> PDE

那么我们其实也可以反推

因为PTE =


Windows 内存管理

VAD

微软和Intel手册叫的不同


返回首页 | 返回主站