TLB(Translation Lookaside Buffer)是 CPU 内部用于缓存线性地址与物理地址映射关系的表。

注意:
TLB在X86体系的CPU中的实际应用最早是从Intel的486CPU开始的,在X86体系的CPU中,一般都设有如下4组TLB:
实验在 2-9-9-12 分页的环境下进行。代码如下:
#include
#include
#include
void *p1, *p2;
unsigned int val1, val2, val3;
unsigned int plt1, plt2;
const unsigned int plt0 = 0xC0000000;
__declspec(naked) void callGate() {
__asm {
push 0x30
pop fs
pushad
pushfd
}
//将 p1 对应物理页挂到 0 地址处
plt1 = ((unsigned int) p1 >> 9 & 0x7FFFF8) | 0xC0000000;
*(unsigned int *) plt0 = *(unsigned int *) plt1;
*(unsigned int *) (plt0 + 4) = *(unsigned int *) (plt1 + 4);
//读取 0 地址处内存
val1 = *(unsigned int *) 0;
//将 p2 对应物理页挂到 0 地址处
plt2 = ((unsigned int) p2 >> 9 & 0x7FFFF8) | 0xC0000000;
*(unsigned int *) plt0 = *(unsigned int *) plt2;
*(unsigned int *) (plt0 + 4) = *(unsigned int *) (plt2 + 4);
//读取 0 地址处内存
val2 = *(unsigned int *) 0;
//刷新 TLB
__asm {
mov eax, cr3
mov cr3, eax
}
//读取 0 地址处内存
val3 = *(unsigned int *) 0;
__asm {
popad
popfd
retf
}
}
int main() {
unsigned char buf[] = {0, 0, 0, 0, 0x48, 0};
p1 = VirtualAlloc((void *) 0x600000, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
p2 = VirtualAlloc((void *) 0x700000, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
printf("%X %X\n", (int) p1, (int) p2);
if (p1 == NULL || p2 == NULL) {
printf("[-] VirtualAlloc failed.");
return 0;
}
*(unsigned int *) p1 = 0x123;
*(unsigned int *) p2 = 0x456;
printf("callGate: %X\n", callGate);
system("pause");
__asm {
pushad
pushfd
call fword ptr buf
popfd
popad
push 0x3b
pop fs
}
printf("val1: %X\nval2: %X\nval3: %X\n", val1, val2, val3);
return 0;
}
运行结果:

可以发现:
这是因为 Cr3 刷新前,0 地址第一次被val1访问时,线性地址与物理地址的对应关系被写入了 TLB 中,因此在对 val2 赋值时,TLB 的记录没有被刷新,访问的还是原来的物理页。
将前面的代码做如下改动:

由于 p1 的 PLT 写入 0 地址对应 PLT 时将 G 位 置 1,刷新 TLB 时不会更新该数据。
在上一实验代码的基础上使用 INVLPG 指令刷新 0 地址对于的 TLB 数据,结果在 PLT 的 G 位置 1 的情况下依然能刷新。

控制寄存器用于控制和确定CPU的操作模式。控制寄存器有五个,分别是:Cr0 Cr1 Cr2 Cr3 Cr4。其中Cr1保留,Cr3为页目录表基址。
结构图:

PE位:启用保护(Protecction Enable)标志
这个标志仅开启段级保护,而没有启用分页机制
若要启用分页机制,那么PE和PG标志都要置位
PG位:分页机制标志
在开启这个标志位之前必须已经或者同时开启PE标志
WP位:写保护(Write Proctect)标志
对于Intel 80486或以上的CPU,CR0的16位是写保护标志
当设置该标志时,处理器会禁止超级用户程序(例如特权级0的程序)向用户级只读页面执行写操作
当CPL<3的时候:
描述:
当CPU访问某个无效页面时,会产生缺页异常,此时,CPU会将引起异常的线性地址存放在CR2中。
结构图:

当CPU访问某个无效页面时,会产生缺页异常,此时,CPU会将引起异常的线性地址存放在CR2中。
结构图:
