// 虚拟存储器2.cpp : Defines the entry point for the application.
//
#include <stdio.h>
#include <stdlib.h>
#define RegistLength 128//块长定义为128
struct Page{
int pagenum;//页号
int signal;//标志
int registnum;//主存块号
int changesignal;//修改标志
int diskadr;//磁盘的位置
}page[7]={0,1,5,0,11,1,1,8,0,12,2,1,9,0,13,3,1,1,0,21,4,0,0,0,22,5,0,0,0,23,6,0,0,0,121};//初始化页表
struct reper{//指令的操作省略
int pagenum;//页号
int unitnum;//单元号
}reper[12]={0,70,1,50,2,15,3,21,0,56,6,40,4,53,5,23,1,37,2,78,4,1,6,84};//初始化指令序列
void main()
{
int i,j,l,k=0;
int P[4]={0,1,2,3};
int phyaddr=0;//物理地址
printf("页表如下:\n");
printf("页号\t标志\t主存块号\t修改标志\t磁盘的位置\n");
for(i=0;i<7;i++)
{
printf("%d\t%d\t%d\t\t%d\t\t%d\n",page[i].pagenum,page[i].signal,page[i].registnum,page[i].changesignal,page[i].diskadr);
}
printf("指令序列如下:\n");
printf("操作\t\t页号\t单元号\n");
for(i=0;i<12;i++)
{
printf("操作省略\t%d\t%d\n",reper[i].pagenum,reper[i].unitnum);
}
for(i=0;i<12;i++)
{
j=reper[i].pagenum;
if(!page[j].signal)//判断该页是否在主存中
{
printf("缺页中断 *%d\n",page[j].pagenum);//不在主存中缺页中断
printf("该页在磁盘中的位置为%d\n",page[j].diskadr);
if(page[P[k]].changesignal)
{//该页修改过了,要从主存块中输出到磁盘
l=P[k];
printf("调出页%d,其调出前相关信息如下\n",l);
printf("%d\t%d\t%d\t%d\t%d\n",page[l].pagenum,page[l].signal,page[l].registnum,page[l].changesignal,page[l].diskadr);
page[l].changesignal=0;
page[l].signal=0;
printf("其调出后相关信息如下\n");
printf("%d\t%d\t%d\t%d\t%d\n",page[l].pagenum,page[l].signal,page[l].registnum,page[l].changesignal,page[l].diskadr);
}
page[j].registnum=page[P[k]].registnum;//总共只有4个主存块,将最早进入页的主存块让出
page[j].signal=1;//模拟该页已经放入主存中
P[k]=page[j].pagenum;
k=(k+1)%4;
printf("该页调入主存后的页表单元状况\n");
printf("%d\t%d\t%d\t%d\t%d\n",page[j].pagenum,page[j].signal,page[j].registnum,page[j].changesignal,page[j].diskadr);
}//缺页中断结束
if((page[j].diskadr%3)!=0)
{
page[j].changesignal=1;//表示该页已经修改过了
printf("该页%d已经被修改过了\n",j);
}
phyaddr=page[j].registnum*128+reper[i].unitnum;
printf("此时第%d条指令的绝对地址为%d\n",i,phyaddr);//地址转换
}
}