本人在另一个地方看到下面这个方法也可以得到某一虚拟地址对应PTE的虚拟地址的,初看起来,还不知道那是什么意思的,实际上它和楼主所说的在本质上是一样的。下面的内容引自《Undocumented Windows NT》:
“
MOV EAX, ESI
AND EAX, 0xFFFFF3FF
SHR EAX, 0A
SUB EAX, 40000000
MOV EAX, ESI
AND EAX, FFCFFFFF
SHR EAX, 14
SUB EAX,3FD00000
当 ESI 寄存器的值为一个虚地址时,这两段代码分别取得页表项和页目录项。 实际中所用的寄存器可能不同,但模式是一样的。 许多于内存管理相关的代码中都会见到此类代码。起初看上去是有些别扭,但他们都是经过2的补码方法高度优化的。 作为练习,试着弄清楚它是如何工作的。提示:页表被映射的起始点在虚地址 0xC0000000,而页目录的则在 0xC0300000。
”
上面引号里的话是原文的,下面是凭本人的理解,对这段代码的解悉:
MOV EAX, ESI
AND EAX, 0xFFFFF3FF
SHR EAX, 0A ;右移12位再左移2位,结果就是右移10位。
SUB EAX, 40000000 ;对EAX而言(不考虑标志位),减去0x40000000和加上0xC0000000是一样的,之后
;EAX便是ESI对应的VA的页表的虚拟地址。
MOV EAX, ESI
AND EAX, FFCFFFFF
SHR EAX, 14 ;右移12+10位再左移2位,结果就是右移20位。
SUB EAX,3FD00000 ;对EAX而言,减去0x3FD00000和加上0xC0300000是一样的
原文说,“当 ESI 寄存器的值为一个虚地址时,这两段代码分别取得页表项和页目录项。”我觉得应是当 ESI 寄存器的值为一个虚地址时,这两段代码分别取得页表项和页目录项的VA。我没看英文版的《Undocumented Windows NT》,不知是不是译错了。