给定虚拟地址找到物理地址
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验报告
班级:030914班
学号:03091389
姓名:杜莉莉
地点:E-208
实验三给定虚拟地址找到物理地址
1.问题描述
任意给一个虚拟地址,通过windbg观察相关数据并找到其物理地址。虚拟地址为0x504002
2.Windows地址转译过程原理
地址转译是指将进程的虚拟地址空间映射到实际物理页面的过程,如下地址转译过程:
页目录
每个进程都有一个页目录,它是内存管理器为了映射进程中所有的页表位置而创建的一个页面。进程页面目录的地址被保护存在内核进程块kprocess中,在x86中,它被映射值虚拟地址0xc0300000。当一个进程正在执行时,cpu可以通过寄存器cr3知道该进程页目录的位置。
页目录由页目录项PDE构成,每个PDE长4字节,描述了进程中所有可能的页表的状态和位置。
页表
进程的页目录指向页表,每个页表占用一个页面,由1024项PTE构成。一个有效的PTE大小为4字节,包含两个主域:数据所在的物理页面的页面帧编号或者内存中一个页面的物理地址的PEN。
虚拟地址结构
由于页目录项有1024个,因此页目录索引为10位;一个页表中含有1024个PTE,因此页表索引也为10位;字节索引为12位.
3.地址转译过程观测及分析
查找页目录地址
输入命令:
kd>!process
输入命令:
Kprocess中有一个域名,名为DirectoryTableBase,对应值0xaf32000,这就是test.exe进程页目录的基址。
查看cr3寄存器中的内容,输入命令:
cr3寄存器中的值和kprocess中记录的页目录基址相同,所以通过cr3寄存器,系统便可以找到当前正在运行的进程页目录的首地址
地址转译过程
给定的虚拟地址为0x504002
PDE的虚拟地址为C0300004,页目录开始的地址为c300000,每个目录项4字节,给定虚拟地址的页目录索引为0x1,故为c0300004。
Fb1b为对应的页表装入内存中的实页号,---DA—UWEV是标识信息。
PTE为c0001410:因为页表从0xc0000000开始,每页为4096(0x1000)字节,每个PTE长度为4字节,由页目录索引值(0x1)给定虚拟地址处于第二个页表上,页表索引为0x104,对应的PTE为0xc0000000+0x1000+0x104*4=0xc0001410。
司机和售票员的例子jincheng.exe
程序代码:
#include
#include
#include
#define WAIT Sleep(1000)//动作间隔的时间
using namespace std;
//信号量
typedef int Semaphore;//信号量数据类型定义
//变量定义
HANDLE hDriver;//司机线程的句柄
HANDLE hBusman;//售票员线程的句柄
DWORD dwDriverId, dwDriverParam = 1;
DWORD dwBusmanId, dwBusmanParam = 1; Semaphore run = 0;
Semaphore stop = 0;
Semaphore action = 1;
typedef int Semaphore;
//用于线程同步
void P(Semaphore &s, HANDLE hT); void V(Semaphore &s, HANDLE hT); void P(Semaphore &s, HANDLE hT){
s-=1;
if(s<0){
SuspendThread(hT);
}
}
void V(Semaphore &s, HANDLE hT){
s+=1;
if(s<=0){
ResumeThread(hT);
}
}
void DriverStartup();//司机启动
void DriverRun();//司机行车
void DriverStop();//司机停车
void BusmanUp();//售票员上客
void BusmanClose();//售票员关门
void BusmanSell();//售票员售票
void BusmanOpen();//售票员开门
void BusmanDown();//售票员下乘客
//与上述相符的具体动作
void DriverStartup(){
P(action,hDriver);
cout<<"Driver:Startup."< V(action,hBusman); } void DriverRun(){ P(action,hDriver); cout<<"Driver:Run."< WAIT; V(action,hBusman); } void DriverStop(){ P(action,hDriver); cout<<"Driver:Stop."< WAIT; V(action,hBusman); } void BusmanUp(){ P(action,hBusman); cout<<"Busman:People up."< V(action,hDriver); } void BusmanClose(){ P(action,hBusman); cout<<"Busman:Close door."< V(action,hDriver); } void BusmanSell(){ P(action,hBusman); cout<<"Busman:Sell ticket."< V(action,hDriver); } void BusmanOpen(){ P(action,hBusman); cout<<"Busman:Open door."< V(action,hDriver); } void BusmanDown(){ P(action,hBusman); cout<<"Busman:people down."< V(action,hDriver); } //线程回调