Windows保护模式学习笔记(十)—— TLB
Windows保護模式學習筆記(十)—— TLB
- 地址解析
- 10-10-12分頁
- 2-9-9-12分頁
- TLB
- TLB結構
- TLB種類
- 練習1:體驗TLB的存在
- 第一步:運行代碼
- 第二步:設置中斷門描述符
- 第三步:繼續運行程序
- 實驗總結
- 練習2:體驗全局頁的意義
- 練習3:INVLPG指令的意義
地址解析
當我們通過一個線性地址訪問一個物理頁(比如:MOV EAX,[0x12345678])時,實際上CPU未必只讀了4個字節。
10-10-12分頁
一共訪問了12個字節,如果跨頁可能更多。
2-9-9-12分頁
一共訪問了20個字節,如果跨頁可能更多。
- 為了提高訪問效率,只能對線性地址與其對應的物理地址做記錄。
- CPU內部做了一張表,用來記錄這些東西。它的效率和寄存器一樣快,名字叫做TLB(Translation Lookaside Buffer)。
- 由于TLB的效率很快,因此它的大小不能太大,少則幾十條,多則也只有上百條。
思考:在一個進程的4GB空間中,有無數個線性地址,但是一個TLB最多只能記錄上百條記錄,那么這張表真的有意義嗎?
TLB
TLB結構
ATTR:屬性
在10-10-12分頁模式下:ATTR = PDE屬性 & PTE屬性
在2-9-9-12分頁模式下:ATTR = PDPTE屬性 & PDE屬性 & PTE屬性
LRU:統計信息
由于TLB的大小有限,因此當TLB被寫滿、又有新的地址即將寫入時,TLB就會根據統計信息來判斷哪些地址是不常用的,從而將不常用的記錄從TLB中移除。
注意:
所以PDE和PTE中有個G標志位(當PDE為大頁時,G標志位才起作用),如果G位為1,刷新TLB時將不會刷新PDE/PTE
G位為1的頁,當TLB寫滿時,CPU根據統計信息將不常用的地址廢棄,保留最常用的地址
TLB種類
TLB在X86體系的CPU中的實際應用最早是從Intel的486CPU開始的,在X86體系的CPU中,一般都設有如下4組TLB:
第一組:緩存一般頁表(4K字節頁面)的指令頁表緩存(Instruction-TLB);
第二組:緩存一般頁表(4K字節頁面)的數據頁表緩存(Data-TLB);
第三組:緩存大尺寸頁表(2M/4M字節頁面)的指令頁表緩存(Instruction-TLB);
第四組:緩存大尺寸頁表(2M/4M字節頁面)的數據頁表緩存(Data-TLB)
注意:以下練習均采用10-10-12分頁模式
練習1:體驗TLB的存在
第一步:運行代碼
注意:在調用門(int 0x20)執行前的任意位置設置斷點,并運行至斷點處
#include <stdio.h> #include <windows.h>DWORD x, y, z;void __declspec(naked) PageOnNull() {__asm{//保存現場push ebpmov ebp, espsub esp, 0x100push ebxpush esipush edi}DWORD* pPTE; // 保存目標線性地址的 PTE 線性地址DWORD* pNullPTE; // 0 地址的 PTE 線性地址pNullPTE = (DWORD*)0xC0000000;// 掛上 0x50000000 所在位置pPTE = (DWORD*)(0xC0000000 + (0x50000000 >> 10)); *pNullPTE = *pPTE;x = *(DWORD*)0;// 掛上 0x60000000 所在位置pPTE = (DWORD*)(0xC0000000 + (0x60000000 >> 10)); *pNullPTE = *pPTE;y = *(DWORD*)0;// 刷新 TLB __asm {mov eax, cr3mov cr3, eax}// 再次讀取 0 地址位置的數據z = *(DWORD*)0;__asm{//恢復現場pop edipop esipop ebxmov esp, ebppop ebpiretd} }int main(int argc, char* argv[]) {DWORD* p5 = (DWORD*)VirtualAlloc((LPVOID)0x50000000, 4, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);DWORD* p6 = (DWORD*)VirtualAlloc((LPVOID)0x60000000, 4, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);if (p5 != (DWORD*)0x50000000 || p6 != (DWORD*)0x60000000){printf("Error alloc!\n");return -1;}*p5 = 0x1234;*p6 = 0x5678;__asm{// 通過中斷門提權int 0x20}printf("1. 讀 0 地址數據:\n");printf("*NULL = 0x%x \n\n", x);printf("2. 給 0 地址重新掛上物理頁\n\n");printf("3. 重新讀取 0 地址數據:\n");printf("*NULL = 0x%x \n\n", y);printf("4. 刷新 TLB \n\n");printf("5. 再次讀取 0 地址數據:\n");printf("*NULL = 0x%x \n", z);return 0; }第二步:設置中斷門描述符
首先在編輯器的反匯編界面查看PageOnNull函數的首地址
因此確定中斷門描述符:0040ee00`00081030
使用WinDbg在IDT[0x20]處寫入中斷門描述符
kd> eq 8003f500 0040ee00`00081030
第三步:繼續運行程序
解除WinDbg中斷,使虛擬機繼續運行,然后繼續向下運行代碼
運行結果:
實驗成功!
實驗總結
練習2:體驗全局頁的意義
略(待補充)
練習3:INVLPG指令的意義
略(待補充)
總結
以上是生活随笔為你收集整理的Windows保护模式学习笔记(十)—— TLB的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows保护模式学习笔记(九)——
- 下一篇: Windows保护模式学习笔记(十二)—