struct
{
unsigned P : 1; // present (1 = present)
unsigned RW : 1; // read/write
unsigned US : 1; // user/supervisor
unsigned PWT : 1; // page-level write-through
unsigned PCD : 1; // page-level cache disabled
unsigned A : 1; // accessed
unsigned D : 1; // dirty
unsigned Reserved : 1;
unsigned G : 1; // global page
unsigned Available : 3; // available to programmer
unsigned PFN : 20; // page-frame number
};
};
}
X86_PTE_4K, *PX86_PTE_4K, **PPX86_PTE_4K;
#define X86_PTE_4K_ sizeof (X86_PTE_4K)
// -----------------------------------------------------------------
typedef struct _X86_PNPE // page not present entry
{
union
{
struct
{
DWORD dValue; // packed value
};
struct
{
unsigned P : 1; // present (0 = not present)
unsigned Reserved1 : 9;
unsigned PageFile : 1; // page swapped to pagefile
unsigned Reserved2 : 21;
};
};
}
X86_PNPE, *PX86_PNPE, **PPX86_PNPE;
#define X86_PNPE_ sizeof (X86_PNPE)
// -----------------------------------------------------------------
typedef struct _X86_PE // general page entry
{
union
{
DWORD dValue; // packed value
X86_PDBR pdbr; // page-directory Base Register
X86_PDE_4M pde4M; // page-directory entry (4-MB page)
X86_PDE_4K pde4K; // page-directory entry (4-KB page)
X86_PTE_4K pte4K; // page-table entry (4-KB page)
X86_PNPE pnpe; // page not present entry
};
}
X86_PE, *PX86_PE, **PPX86_PE;
#define X86_PE_ sizeof (X86_PE)
列表 4-3. i386 的 PDBR 、 PDE 、 PTE 和 PNPE
在 列表 4-4 中,我增加了线性地址的结构化表示 。这些结构是 图 4-3 和 4-4 中的“线性地址”的正式形式 。
l X86_LINEAR_4M 该结构是指向 4MB 数据页的线性地址的正式形式,如 图 4-4 所示 。页目录索引( PDI )是一个页目录的索引,页目录地址由 PDBR 给出,使用 PDI 可选择页目录中的一个 PDE。22 位的 Offset 成员指向一个目标地址,此目标地址对应 4MB 的物理页 。
l X86_LINEAR_4K 是一个 4KB 线性地址类型的变量,如 图 4-3 所示 。该结构由三个位域组成:和 4MB 地址类似,高 10 位为 PDI,用来选择一个 PDE ;页表索引 PTI 的任务与 PDI 相似,指向由 PDE (该 PDE 由前面的 PDI 指定)确定的页表中的一个 PTE ;剩余的 12 个位是在 4KB 物理页中的偏移量 。
l X86_LINEAR 是另一个为使用方便而加入的结构 。该结构只是简单的将 X86_LINEAR_4K 和 X86_LINEAR_4M 联合为一个数据类型 。详见 列表 4-4。
typedef struct _X86_LINEAR_4M // linear address (4-MB page)
{
union
{
struct
{
PVOID pAddress; // packed address
};
struct
{
unsigned Offset : 22; // offset into page
unsigned PDI : 10; // page-directory index
};
};
}
X86_LINEAR_4M, *PX86_LINEAR_4M, **PPX86_LINEAR_4M;
#define X86_LINEAR_4M_ sizeof (X86_LINEAR_4M)
// -----------------------------------------------------------------
typedef struct _X86_LINEAR_4K // linear address (4-KB page)
{
union
{
struct
{
PVOID pAddress; // packed address
};
struct
{
unsigned Offset : 12; // offset into page
unsigned PTI : 10; // page-table index
unsigned PDI : 10; // page-directory index
};
};
}
X86_LINEAR_4K, *PX86_LINEAR_4K, **PPX86_LINEAR_4K;
#define X86_LINEAR_4K_ sizeof (X86_LINEAR_4K)
// -----------------------------------------------------------------
typedef struct _X86_LINEAR // general linear address
{
union
{
PVOID pAddress; // packed address
X86_LINEAR_4M linear4M; // linear address (4-MB page)
推荐阅读
- 1 《Undocumented Windows 2000 Secrets》翻译 --- 第四章
- Windows 2000下的Raw Socket编程
- Windows 2000开发过程中一些有趣的数据
- Windows2000软件冲突一例
- 大叔与少年什么时候开始播
- 盛世嫡妃好看吗
- 命令篇 Windows 2000/XP的CMD命令教程 (2)
- 如何手动删除 Windows NT 或 Windows 2000
- Windows 2000系统编程——进程的创建
- 4 《Undocumented Windows 2000 Secrets》翻译 --- 第四章