(11) [保护模式]TLB

本文详细介绍了TLB(Translation Lookaside Buffer)的工作原理,包括其作为快表的角色,如何通过全局位G来决定是否换出,以及在x86架构中不同类型的TLB。通过实例展示了TLB在CR3刷新时的行为,说明了G位为0和1时的不同效果,并探讨了INVLPG指令对TLB的刷新操作。内容深入浅出,有助于理解CPU内存管理的细节。
摘要由CSDN通过智能技术生成

TLB是什么

简单来说TLB (translation lookaside buffer) 是一个类似cache (快表) 的东西,不知道什么是cache那只需要知道——快表,快就完了

CPU读取两个相邻的地址的时候都要拆分一次PDE,PTE,非常的麻烦,能不能把线性地址、物理页和属性对应起来,这样每次CPU只需要查看这个对应关系表就行了。所以TLB就是这么一个对应关系表(TLB一核一个,TLB不会太大,所以当TLB满了以后,不常用的会被删掉)

那么CPU怎么知道什么是常用的什么是不常用的呢?

  1. G位表示全局位,G = 1不会被换出。全局位一般使用在高2G的内核上,内核程序是所有应用程序共享的,所以很常用,不应该换出
  2. 猜测有一个或多个位用于统计是否是常用到的地址,不常用的换出
  3. 进程切换,线程切换时,CR3变化,代表这一块地址暂时不会被访问了,所以直接全部刷新

x86中一般有四组TLB
4. 缓存一般页表(4K字节页面)的指令页表缓存(Instruction-TLB)
5. 缓存一般页表(4K字节页面)的数据页表缓存(Data-TLB)
6. 缓存大尺寸页表(2M/4M字节页面)的指令页表缓存(Instruction-TLB)
7. 缓存大尺寸页表(2M/4M字节页面)的数据页表缓存(Data-TLB)



验证TLB存在

这里是把之前的代码稍作修改后,直接使用

#include <windows.h>
#include <stdio.h>

PDWORD pde, pte, pde0, pte0;
DWORD get0value;

void __declspec(naked) func(){ 
	_asm{
		pushad
		pushf
		// 挂物理页, 注意G == 1
		mov dword ptr ds:[0xC0000000], 0x11111867
		// 给 (void*)0 赋值,这将写入TLB
		mov dword ptr ds:[0x0], 0x87654321
		// 物理页切换
		mov dword ptr ds:[0xC0000000], 0x22222867
		// 读取 (void*0) 的值
		mov eax, dword ptr ds:[0x0]
		mov get0value, eax

		popf
		popad
		retf 
	}
}


int main(){
	BYTE addrs[6] = {0x00, 0x00, 0x00, 0x00, 0x48, 0x00 };
	int selector = 0x0008;

	printf("windbg input:\t eq 8003f048  %04xEC00`%04x%04x\n", 
	  (((DWORD)&func)>>16), selector, (DWORD)&func & 0xFFFF);
	
	_asm{
		push fs
		call fword ptr[addrs]
		pop fs
	}
	
	printf("%x\n", get0value); //打印 指针0 的值
	
	return 0;
}             

在这里插入图片描述



当CR3刷新时,TLB换出

TLB在CR3刷新时换出,但G == 0时,TLB不会换出

修改上面的代码(G==0)

#include <windows.h>
#include <stdio.h>

PDWORD pde, pte, pde0, pte0;
DWORD get0value;

void __declspec(naked) func(){ 
	_asm{
		pushad
		pushf
		// 挂物理页, 注意G == 0
		mov dword ptr ds:[0xC0000000], 0x11111067
		// 给 (void*)0 赋值,这将写入TLB
		mov dword ptr ds:[0x0], 0x87654321
		// 物理页切换
		mov dword ptr ds:[0xC0000000], 0x22222067
		
		//加入刷新CR3的代码
		mov eax,cr3
		mov cr3,eax
		
		// 读取 (void*0) 的值
		mov eax, dword ptr ds:[0x0]
		mov get0value, eax

		popf
		popad
		retf 
	}
}

int main(){
	// 不变...
}

在这里插入图片描述


G == 1

#include <windows.h>
#include <stdio.h>

PDWORD pde, pte, pde0, pte0;
DWORD get0value;

void __declspec(naked) func(){ 
	_asm{
		pushad
		pushf
		// 挂物理页, 注意G == 1
		mov dword ptr ds:[0xC0000000], 0x11111167
		mov dword ptr ds:[0x0], 0x87654321
		mov dword ptr ds:[0xC0000000], 0x22222167
		
		mov eax,cr3
		mov cr3,eax
		
		mov eax, dword ptr ds:[0x0]
		mov get0value, eax

		popf
		popad
		retf 
	}
}

int main(){
	// 不变...
}

在这里插入图片描述



INVLPG指令

可以使用INVLPG指令刷新指定地址的TLB项

#include <windows.h>
#include <stdio.h>

PDWORD pde, pte, pde0, pte0;
DWORD get0value;

void __declspec(naked) func(){ 
	_asm{
		pushad
		pushf
		// 挂物理页, 注意G == 1
		mov dword ptr ds:[0xC0000000], 0x11111167
		mov dword ptr ds:[0x0], 0x87654321
		mov dword ptr ds:[0xC0000000], 0x22222167
		
		INVLPG dword ptr ds:[0x0]
		
		mov eax, dword ptr ds:[0x0]
		mov get0value, eax

		popf
		popad
		retf 
	}
}

int main(){
	// 不变...
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值