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分页

  1. CPU先通过线性地址找到对应的PDE:4个字节
  2. CPU再通过PDE和线性地址找到PTE:4个字节
  3. 最后再通过PTE找到对应物理页:4个字节

一共访问了12个字节,如果跨页可能更多。

2-9-9-12分页

  1. 找到PDPTE:8个字节
  2. 找到PDE:8个字节
  3. 找到PTE:8个字节
  4. 最后找到物理页:4个字节

一共访问了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中移除

注意

  1. 不同的CPU,TLB大小不同
  2. 只要Cr3发生变化,TLB立即刷新,一核一套TLB
  3. 由于操作系统的高2G映射基本不变,因此如果Cr3改了,TLB刷新的话,重建高2G以上很浪费。
    所以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中断,使虚拟机继续运行,然后继续向下运行代码

运行结果:

实验成功!

实验总结

  1. 可以发现,在x被赋值完成后,即使0地址被挂上了新的物理页,再对y进行赋值,x和y输出的值是相同的
  2. 但是在Cr3刷新后,0地址没有被挂上新的物理页,对z进行赋值后,z却输出了新的值
  3. 这是因为Cr3刷新前,0地址第一次被x访问时,线性地址与物理地址的对应关系被写入了TLB中,因此在对y赋值时,TLB的记录没有被刷新,访问的还是原来的物理页

练习2:体验全局页的意义

略(待补充)

练习3:INVLPG指令的意义

略(待补充)

Windows保护模式学习笔记(十)—— TLB相关推荐

  1. Windows保护模式学习笔记(十四)—— 阶段测试

    Windows保护模式学习笔记(十四)-- 阶段测试 题目一 解题步骤 题目二 解题步骤 题目一 描述:给定一个线性地址,和长度,读取内容 int ReadMemory(OUT BYTE* buffe ...

  2. Windows保护模式学习笔记(十二)—— 控制寄存器

    Windows保护模式学习笔记(十二)-- 控制寄存器 控制寄存器 Cr0寄存器 Cr2寄存器 Cr4寄存器 控制寄存器 描述: 控制寄存器有五个,分别是:Cr0 Cr1 Cr2 Cr3 Cr4 Cr ...

  3. Windows保护模式学习笔记(十三)—— PWTPCD

    Windows保护模式学习笔记(十三)-- PWT&PCD 要点回顾 CPU缓存 CPU缓存与TLB的区别 PWT(Page Write Through) PCD(Page Cache Dis ...

  4. Windows保护模式学习笔记(七)—— PDEPTE

    Windows保护模式学习笔记(七)-- PDE&PTE Cr3 PDE(页目录表项) PTE(页表项) 物理页的属性 10-10-12分页的补充 实验1:证明PTE的特征1 第一步:选择一个 ...

  5. Windows保护模式学习笔记(九)—— 2-9-9-12分页

    Windows保护模式学习笔记(九)-- 2-9-9-12分页 要点回顾 10-10-12分页 原理 环境配置 2-9-9-12分页 原理 PDPTE PDE PTE XD/NX标志位 环境配置 实验 ...

  6. Windows保护模式学习笔记(八)—— 页目录表基址/页表基址

    Windows保护模式学习笔记(八)-- 页目录表基址/页表基址 要点回顾 一.页目录表基址 实验:拆分线性地址C0300000,并查看其对应的物理页 第一步:打开一个进程,获得它的Cr3 第二步:查 ...

  7. Windows保护模式学习笔记(六)—— 10-10-12分页

    Windows保护模式学习笔记(六)-- 10-10-12分页 基本概念 4GB内存空间 有效地址-线性地址-物理地址 有效地址与线性地址 物理地址 控制寄存器:Cr3 10-10-12分页 实验:通 ...

  8. Windows保护模式学习笔记(五)—— 任务段任务门

    Windows保护模式学习笔记(五)-- 任务段&任务门 要点回顾 任务段 TSS (Task-state segment ) TR段寄存器 TR段寄存器的读写 TSS段描述符 实验:加载自定 ...

  9. Windows保护模式学习笔记(四)—— 中断门陷阱门

    Windows保护模式学习笔记(四)-- 中断门&陷阱门 要点回顾 中断描述符表(IDT) 一.中断门 实验:构造一个中断门 第一步:初步构造参数 第二步:确定 Offset in Segme ...

最新文章

  1. KOA2路由koa-router实现类似express router的文件结构设计---KOA入门学习
  2. Charles 4.2.1 HTTPS抓包
  3. java程序应用编写如何判断文本框里面的数据类型
  4. 巧用Win2003负载平衡服务实现LCS2005企业版的部署:LCS2005系列之五
  5. 3481. 阶乘的和
  6. 标星7000+,这个 Python 艺术二维码生成器厉害了!
  7. js进阶 13 jquery动画函数有哪些
  8. 使用ISA Server保护内部的web服务器
  9. “非IE内核浏览器”第一阶段开发计划发布
  10. 阶段3 2.Spring_06.Spring的新注解_1 spring的新注解-Configuration和ComponentScan
  11. 数据库课程设计 论坛系统—— 系统详细设计说明书
  12. 一个屌丝程序员的青春(二一一)
  13. echarts图表 tooltip提示框,xAxis X轴,formatter自定义
  14. saltstack return mysql_10-saltstack 数据返回到MySQL
  15. 基于leaflet-velocity的二维动态风场展示
  16. 苹果无需越狱了!通过苹果签名轻松安装IPA文件
  17. background-image
  18. linux rpm 装 mac,在linux上搭建用于mac时间机器备份的server
  19. 微信第三方服务平台开发(一)
  20. 在进行USB CDC类开发时,无法发送64整数倍的数据(续)

热门文章

  1. DL之GRU:GRU算法相关论文、建立过程(基于TF)、相关思路配图集合、TF代码实现
  2. 使用juery在iframe内部访问父页面元素
  3. 文章内容页调用所属栏目地址的标签
  4. 日记-2017-7-24-cp-css-django/media
  5. iOS开源项目周报0316
  6. Python GUI编程--Tkinter
  7. 初探WCF 如何在配置文件中指定Address?
  8. sql当等INSERT之后获取主键值
  9. SPI FLASH 分区情况
  10. ili9341屏幕在断电一段时间后首次上电白屏问题