X86_LINEAR_4K linear4K; // linear address (4-KB page)
};
}
X86_LINEAR, *PX86_LINEAR, **PPX86_LINEAR;
#define X86_LINEAR_ sizeof (X86_LINEAR)
列表 4-4. i386 的线性地址
宏和常量
列表 4-5 给出的定义是对 列表 4-2 到 列表 4-4 所示结构的补充,让我们可以更容易的和 i386 内存管理一起工作 。列表 4-5 的定义可以分为三大组 。第一组用于控制线性地址:
1. X86_PAGE_MASK 、 X86_PDI_MASK 和 X86_PTI_MASK 都是位掩码( bit mask ),用来选择线性地址中的某一部分 。它们都基于常量: PAGE_SHIFT (12) 、 PDI-SHIFT (22) 和 PTI-SHIFT (12),这些常量定义于 Windows 2000 DDK 的头文件 ntddk.h 中 。X86_PAGE_MASK 等价于 0xFFFFF000,可有效的屏蔽 4KB 线性地址( X86_LINEAR_4K )中的偏移量部分 。X86_PDI_MASK 等价于 0xFFC00000,显然这可从线性地址中提取高 10 位的 PDI。X86_PTI_MASK 等价于 0x003FF0000,用于屏蔽线性地址中除 PTI 外的所有位 。
2. X86_PAGE() 、 X86_PDI() 和 X86_PTI() 使用上面的常量来计算给定线性地址的页索引、 PDI 和 PTI。X86_PAGE() 一般用来从 Windows 2000 的 PTE 数组(该数组首地址为: 0xC0000000 )中读取一个 PTE。X86_PDI() 和 X86_PTI() 只是针对给定的指针,简单的使用 X86_PDI_MASK 或 X86_PTI_MASK,并将得到的索引移动到最右边 。
3. X86_OFFSET_4M() 和 X86_OFFSET_4K() 分别从 4MB 或 4KB 线性地址中提取偏移量部分 。
4. X86_PAGE_4M 和 X86_PAGE_4K 根据 DDK 中的常量 PDI_SHIFT 和 PTI_SHIFT 来计算 4MB 和 4KB 页的大小 。X86_PAGE_4M=4,194,304,X86_PAGE_4K=4,096。注意,X86_PAGE_4K 等价于 DDK 常量 PAGE_SIZE,该常量也定义于 ntddk.h 中 。
5. X86_PAGES_4M 和 X86_PAGES_4K 分别表示 4GB 地址空间中可容纳的 4MB 或 4KB 页的总数 。X86_PAGES_4M 等价于 1,024,X86_PAGES_4K 等价于 1,048,576。
#define X86_PAGE_MASK (0 - (1 << PAGE_SHIFT))
#define X86_PAGE(_p) (((DWORD) (_p) & X86_PAGE_MASK) >> PAGE_SHIFT)
#define X86_PDI_MASK (0 - (1 << PDI_SHIFT))
#define X86_PDI(_p) (((DWORD) (_p) & X86_PDI_MASK) >> PDI_SHIFT)
#define X86_PTI_MASK ((0 - (1 << PTI_SHIFT)) & ~X86_PDI_MASK)
#define X86_PTI(_p) (((DWORD) (_p) & X86_PTI_MASK) >> PTI_SHIFT)
#define X86_OFFSET(_p,_m) ((DWORD_PTR) (_p) & ~(_m))
#define X86_OFFSET_4M(_p) X86_OFFSET (_p, X86_PDI_MASK)
#define X86_OFFSET_4K(_p) X86_OFFSET (_p, X86_PDI_MASK|X86_PTI_MASK)
#define X86_PAGE_4M (1 << PDI_SHIFT)
#define X86_PAGE_4K (1 << PTI_SHIFT)
#define X86_PAGES_4M (1 << (32 - PDI_SHIFT))
#define X86_PAGES_4K (1 << (32 - PTI_SHIFT))
// -----------------------------------------------------------------
#define X86_PAGES 0xC0000000
#define X86_PTE_ARRAY ((PX86_PE) X86_PAGES)
#define X86_PDE_ARRAY (X86_PTE_ARRAY(X86_PAGES >> PTI_SHIFT))
// -----------------------------------------------------------------
#define X86_SEGMENT_OTHER 0
#define X86_SEGMENT_CS 1
#define X86_SEGMENT_DS 2
#define X86_SEGMENT_ES 3
#define X86_SEGMENT_FS 4
#define X86_SEGMENT_GS 5
#define X86_SEGMENT_SS 6
#define X86_SEGMENT_TSS 7
// -----------------------------------------------------------------
#define X86_SELECTOR_RPL 0x0003
#define X86_SELECTOR_TI 0x0004
#define X86_SELECTOR_INDEX 0xFFF8
#define X86_SELECTOR_SHIFT 3
#define X86_SELECTOR_LIMIT (X86_SELECTOR_INDEX >>
X86_SELECTOR_SHIFT)
// -----------------------------------------------------------------
#define X86_DESCRIPTOR_SYS_TSS16A 0x1
#define X86_DESCRIPTOR_SYS_LDT 0x2
#define X86_DESCRIPTOR_SYS_TSS16B 0x3
#define X86_DESCRIPTOR_SYS_CALL16 0x4
#define X86_DESCRIPTOR_SYS_TASK 0x5
#define X86_DESCRIPTOR_SYS_INT16 0x6
#define X86_DESCRIPTOR_SYS_TRAP16 0x7
#define X86_DESCRIPTOR_SYS_TSS32A 0x9
#define X86_DESCRIPTOR_SYS_TSS32B 0xB
推荐阅读
- 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》翻译 --- 第四章