【2021.03.26】PDE、PTE

要点回顾

前文简单了解了80x86的 10-10-12 分页机制,本篇文章继续学习。

PDE与PTE

CR3:唯一一个存储物理地址的寄存器。

在Windows中,页大小是4KB。在后期会接触到另一种页,有4MB大小,称为大页。

CR3里面存储的地址,指向的是页目录表(PDT),表中每个成员称为PDE(页目录表项/页目录项)。

页目录表(PDT)中每个成员(PDE)又指向另一张表,该表称为页表(PTT)。

页表(PTT)的大小与页目录表(PDT)一样是4KB,其中存储的成员有1024个,每个成员占4字节。

每个页表中的成员称为PTE(页表项),PTE指向的才是真正的物理页。

无论是PDE或者PTE,都是4字节。它的十六进制形式的后三位存储的是属性。

前文学习过了10-10-12分页形式,那么为什么要这么分呢?

一个物理页是4096字节,刚好是2的12次方。所以,需要有12个二进制位,才能找遍所有的物理页。

指向相同物理页

  1. PTE可以指向物理页,也可以没有指向物理页。
  2. 多个PTE可以指向一同一个物理页。
  3. 一个PTE只能指向一个物理页。

实验

拆分0地址,观察PTE是否有物理页,并向0地址读写数据。

1.寻找CR3

2.找到PDE

!dd 3ac17000 + 0,这个0也可以不用加直接写了。

3.找到PTE

不要忘了,把十六进制后3位修改为0。

!dd 0bb39000 + 0

PTE里存储的值是空的,说明当前的PTE没有指向物理页。

有编程经验的读者可能会知道,0地址是没办法往里面写入数据,也没有办法读取数据的,会报错。

那么现在就要往0地址中写入数据并且把数据读取出来,可不可以呢?

可以。

如果想向0地址写入数据或读取数据,只需要给它挂上一个物理页,即可。

代码

#include "stdafx.h"

int main(int argc, char* argv[])
{
    int x = 1;

    printf("x的地址:%x\n", &x);

    getchar();

    //向0地址写入数据
    *(int*)0 = 123;

    //读取0地址上的数据
    printf("0地址数据:%x\n", *(int*)0);

    return 0;
}

定义了一个变量(x),赋值为1。这个1里面肯定是有物理页的,当执行的时候,系统会分配内存给它。

*(int*)0 = 123;这行代码,如果直接运行肯定是会报错的,因为0的线性地址没有物理页,是写不进去的。

后面的读取也是一样,会报错。

当程序运行的时候,将 int x = 1; 的PDE、PTE里面的值挂到0上,即可。

7b转换为10进制,就是123。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值