轉自: http://www.pediy.com/kssd/pediy10/62497.html
在《JIURL玩玩Win2k內存篇 分頁機制 (三)》中提到計算虛擬地址對應PTE地址的公式,如下:
PTE_Addr = (VirtualAddr >> 12) * 4 + 0xC0000000
其實很簡單,因爲1024個頁表被映射在0xC0000000 - 0xC03FFFFF地址中,暫且不理會頁目錄被映射到哪,只要知道頁目錄裏的1024個頁目錄項分別指向0xC0000000 - 0xC03FFFFF地址中的1024個頁表就行了(其實這是因爲頁目錄和一個頁表完全重合的原因,見《JIURL玩玩Win2k內存篇 分頁機制 (四)》),這樣就可以得到一個關係,頁目錄索引n指向的頁表就等於0xC0000000 + n * 頁表大小,一個頁表的大小是1024 * 4 = 4096 = 2的12次方,得到了頁表,在加上頁表索引就可以得到頁表項(PTE)的地址了,用公式表示就是如下:
//爲了縮短表達式,用VA表示虛擬地址 // 頁目錄索引 頁表索引 PTE_Addr=((VA&0xffc00000)>>22)*4096+((VA&0x3ff000)>>12)*4+0xc0000000 =(((VA&0xffc00000)>>22)<<12)+(((VA&0x3ff000)>>12)<<2)+0xc0000000 =((VA&0xffc00000)>>10)+((VA&0x3ff000)>>10)+0xc0000000 =((VA&0xffc00000)+(VA&0x3ff000)>>10)+0xc0000000 =((VA&(0xffc00000|0x3ff000))>>10)+0xc0000000 =((VA&0xfffff000)>>10)+0xc0000000 =(((VA&0xfffff000)>>12)<<2)+0xc0000000 =((VA&0xfffff000)>>12)*4+0xc0000000
PTE_Addr = (VirtualAddr >> 12) * 4 + 0xC0000000
PTE = ((VA >> 12) << 2 ) & 0x3FFFC + 0xc0000000;
PTE = ((VA >> 12) << 2 ) & 0x3FFFFC + 0xc0000000;
PTE = (VA >> 12) * 4 + 0xc0000000;
上面說的都是在32位 x86 非PAE的情況下,PAE情況下略有不同,有時間再整理