⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shiyan 2.cpp

📁 通过请求页式存储管理中页面置换算法模拟设计
💻 CPP
字号:
#include <iostream>

#include <iostream.h>

#include <iomanip.h>

#include <ctype.h>

#define N 6//实验中假定的页表长度

#define M 4   //主存物理块数

struct

{int  lnumber;  //页号

 int  flag;       //表示该页是否在主存,"1"表示在主存,"0"表示不在主存

 int  pnumber;    //该页所在主存块的块号

 int  write;      //该页是否被修改过,"1"表示修改过,"0"表示没有修改过

 int  dnumber;    //该页存放在磁盘上的位置,即磁盘块号

}page[N];     //页表定义

 

int p[M];  //用数组模拟]FIFO算法中的队列(使用循环队列)

int head;

void initial(void);  

int do_mmap(int); //模拟地址转换

void do_page_fault(int); //缺页中断处理程序

void run_first_instructon(int); //执行进程的第一条指令

void run_a_instruction(int);    //CPU执行一条指令

void print_page_and_fifoqueue(void);   //输出页表和FIFO队列

 

main()

{

    int laddress, paddress;  //逻辑地址,物理地址

    int lnumber, ad, pnumber;   //页号,页内地址和物理块号

    initial(); 

    print_page_and_fifoqueue(); //输出页表和FIFO队列

    

    run_first_instructon(0x0000);   //运行进程的第一条指令的地址

    cout<<"输入下一条指令的逻辑地址(0~32767)(-1 to end)"<<endl;

    cin>>laddress;

    while(laddress>32767){

       cout<<"输入错误! 请重新输入下一条指令的逻辑地址(0~32767)(-1 to end)"<<endl;

       cin>>laddress;

    }

    while(laddress!=-1){ 

       lnumber=laddress>>10;    //取逻辑地址的页号lnumber

       if(page[lnumber].flag==1){  //指令所在的页面已装入在内存中

           paddress=do_mmap(laddress); //形成物理地址

 

           cout<<paddress<<"输出转换后的物理地址"<<endl;

           run_a_instruction(paddress);               

       cout<<"此指令执行是否修改所在页lnumber="<<lnumber<<"(y/n?) ";

           char change;

           cin>>change;

           if(tolower(change)=='y'){

           page[lnumber].write=1;              print_page_and_fifoqueue();

           }

       }

       else{  //缺页中断

           cout<<lnumber<<"输出该页的页号--表示硬件产生缺页中断"<<endl;

           do_page_fault(lnumber);  //直接转去缺页中断处理

 

           continue;  //本循环结束,重新执行指令

       }

 

       cout<<"输入下一条指令的逻辑地址((0~32767),-1 to end)\n";

       cin>>laddress;

       while(laddress>32767){   //输入正确性检测

           cout<<"输入错误! 请重新输入下一条指令的逻辑地址(0~32767)(-1 to end)"<<endl;

           cin>>laddress;

       }

    }

    

    cout<<"进程运行结束!"<<endl;

    system("PAUSE");

    return 0;

}

 

 //手工初始化页表和p[M]队列

void initial(void)

{

    int i;

    

    for(i=0; i<=5; i++){

       page[i].lnumber=i;          

       if(i<=M-1){   //预装入算法初始化页表的前四项

           cout<<"输入页号为 "<<i<<" 所在内存的物理块号(预装入前四个页面):";

           cin>>page[i].pnumber;

           page[i].flag=1;   //存在标志置1

       }

    }

    

    //初始化FIFO的队列

    head=0;

    for(i=0; i<=M-1; i++)

       p[i]=i;

}

 

//输出页表和FIFO队列

void print_page_and_fifoqueue(void)

{

    int i;

    cout<<"输出页表!\n";

    cout<<setw(10)<<"lnumber"<<setw(9)<<"flag"<<setw(10)<<"pnumber"

       <<setw(10)<<"write"<<setw(10)<<"dnumber"<<endl;

    for(i=0; i<=N-1; i++)        cout<<setw(7)<<page[i].lnumber<<setw(10)<<page[i].flag<<setw(10)<<page[i].pnumber

           <<setw(10)<<page[i].write<<setw(10)<<page[i].dnumber<<endl;

 

    cout<<"输出FIFO对列:\n";

    cout<<setw(10)<<"NO"<<setw(40)<<"page(已在主存的页号lnumber)\n";

    cout<<"head="<<head<<endl;

    for(i=0; i<=M-1;i++)

       cout<<setw(10)<<i<<setw(15)<<p[i]<<endl;

}

 

 

//模拟地址转换

int do_mmap(int laddress)

{

    int lnumber, ad, pnumber, paddress;

 

    lnumber=laddress>>10;    //取逻辑地址的页号lnumber

 

    ad=laddress&0x3ff;   //页内地址

    pnumber=page[lnumber].pnumber;  //从页表中取得块号pnumber

    paddress=pnumber<<10|ad;

 

    return paddress;

}

 

//CPU执行一条指令,输出物理地址表示指令执行完成

void run_a_instruction(int paddress)

{

    cout<<paddress<<" 输出物理地址--表示指令执行完成"<<endl;

}

 

//执行进程的第一条指令

void run_first_instructon(int laddress)

{

    int lnumber, ad, pnumber, paddress;

 

    lnumber=laddress>>10;    //取逻辑地址的页号

    if(page[lnumber].flag==1)   

    paddress=do_mmap(laddress); //形成物理地址    

    

    cout<<paddress<<"输出转换后的物理地址"<<endl;

    run_a_instruction(paddress);

 

cout<<"此指令执行(0x0000)是否修改所在页面lnumber="<<lnumber<<"(y/n?) ";

    char change;

    cin>>change;

    if(tolower(change)=='y'){   //若指令执行完时修改了页面,则置write标志位位1

       page[lnumber].write=1;

       print_page_and_fifoqueue();

    }

 

cout<<"********第一条指令执行完成(地址为0x0000)***********"<<endl;

}

 

//页面写回磁盘

void write_to_harddisk(int j)

{

    cout<<j<<"输出已修改的淘汰的页号--表示该页写回了磁盘"<<endl;

}

 

//缺页中断处理程序

void do_page_fault(int lnumber)

{

    int j; //j是选择淘汰的页

 

    j=p[head];

    p[head]=lnumber;  //lnumber是新装入的页号

    head=(head+1)%M;

    

    //若淘汰出主存的页j已修改,则写会磁盘

    if(page[j].write==1)

       write_to_harddisk(j);    //页j写回磁盘

 

    //修改页表

    page[j].flag=0;   //页表中第j页的存在标志为0

    page[lnumber].flag=1;    //页表第lnumber的存在标志为1

    page[lnumber].write=0;   //页表第lnumber的修改标志为0

    page[lnumber].pnumber=page[j].pnumber; //第拉怒目布尔页的主存块号为第j页原主存块号

 

    cout<<lnumber<<"输出该页--表示该页调入了主存"<<endl;

    cout<<"按任意键将查看“页面置换”之后的页表page[N]和FIFO队列信息"<<endl;

    system("PAUSE");

    print_page_and_fifoqueue();

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -