模拟虚存管理

 

1、页表的数据结构


页号

标志

主存块号

修改位

外存地址


struct PageItem {
         unsigned pageID;         // 作业的页号
         unsigned outMAddr;    // 该页在外存上的地址
         bool state;                    // 该页是否调入内存,若未调入内存,则blockID和modify字段无效
         unsigned blockID;         // 该页对应的内存物理块号
         bool modify;                 // 该页是否被修改过
};


初始页表结构:

0 1 5 011 1
1 1 8 012 1
2 1 9 013 0
3 1 10 015 0
4 0 0 017 0
5 0 0 025 0
6 0 0 212 0
7 0 0 213 0


2、指令的数据结构


操作

页号

单元号(偏移量)


struct Instruction{
         string OPC;
         unsigned OPAPageID;
         unsigned OPAUnitID;
};


指令序列表:

+ 0 040
+ 1 050
* 2 016
存 3 022
取 0 054
- 6 040
移位 4 052
+ 5 022
存 1 034
取 7 056
+ 4 002
取 6 076



3、地址变换机构算法


 

4、缺页中断机构算法

采用FIFO置换算法,流程图如下:


 

队列进出情况:

页面走向

0

1

2

3

0

6

4

5

1

7

4

6

页框

0

0

0

0

 

1

2

3

6

4

 

5

 

1

1

1

 

2

3

6

4

5

 

1

 

 

2

2

 

3

6

4

5

1

 

7

 

 

 

3

 

6

4

5

1

7

 

6

 


5、源程序

#define_CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<queue>
#include<vector>
#include<string>
#include<cassert>
usingnamespace std;
 
const intPAGE_NUMBER = 8; // 作业所占的页数
const intBLOCK_NUMBER = 4; // 系统最多为作业分配的块数
const intBLOCK_SIZE = 64;     // 主存的每块长度
 
structPageItem {
         unsigned pageID;    // 作业的页号
         unsigned outMAddr;        // 该页在外存上的地址
         bool state;                          // 该页是否调入内存,若未调入内存,则blockID和modify字段无效
         unsigned blockID;    // 该页对应的内存物理块号
         bool modify;              // 该页是否被修改过
 
         // 默认构造函数
         PageItem()
                   :pageID(0),
                   blockID(0),
                   state(false),
                   modify(false),
                   outMAddr(0){}
 
         // 构造函数
         PageItem (
                   unsigned _pageID,
                   unsigned _blockID,
                   bool _state,
                   bool _modify,
                   unsigned _outMAddr)
                   :pageID(_pageID),
                   blockID(_blockID),
                   state(_state),
                   modify(_modify),
                   outMAddr(_outMAddr){}         
};
 
structInstruction {
         string OPC;
         unsigned OPAPageID;
         unsigned OPAUnitID;
};
 
//FIFOQueue的最大长度即系统最多为作业分配的块数BLOCK_NUMBER
voidInterrupt(vector<PageItem> &pageTable, queue<unsigned>&FIFOQueue, const unsigned visitPageID)
{
         assert(FIFOQueue.size() <=BLOCK_NUMBER);
 
         // 按书上给的一定队满,待改进
         if (FIFOQueue.size() == BLOCK_NUMBER)       // 队满则置换,换出队头
         {
                   unsigned num =FIFOQueue.front();         // 队头的页号num
                   pageTable[num].state = false;
                   if (pageTable[num].modify)
                   {
                            cout << "页" << num <<"被修改过,写回磁盘" << endl;
                   }
                   cout << "调页" << num <<"到磁盘" << endl;
                   FIFOQueue.pop();
                   pageTable[visitPageID].blockID= pageTable[num].blockID;
         }
         //pageTable[visitPageID].outMAddr =             // 队不满时实际应按内存分配算法给出该页分配到的物理块号
         cout << "调入页" << visitPageID<< endl;
         pageTable[visitPageID].state = true;
         pageTable[visitPageID].modify = false;
         FIFOQueue.push(visitPageID);
         // 实际还应修改内存分块表
}
 
intmain(int argc, char **argv)
{
         freopen("cin.txt","r", stdin);
 
         vector<PageItem>pageTable(PAGE_NUMBER);    // 作业在内存的页表
         queue<unsigned> FIFOQueue;                                              //系统为作业分配的块队列,元素为该页的页号
         for (int i = 0; i < PAGE_NUMBER;++i)
         {
                   cin >>pageTable[i].pageID
                            >>pageTable[i].state
                            >>pageTable[i].blockID
                            >> pageTable[i].outMAddr
                            >>pageTable[i].modify;
                   if (pageTable[i].state)
                   {
                            FIFOQueue.push(i);
                   }
         }
 
         Instruction ins;
         int cnt = 1;
         while (cin >> ins.OPC >>ins.OPAPageID >> ins.OPAUnitID)    //取指
         {
                   cout << "执行指令" << cnt++ <<endl;
                   unsigned visitPageID =ins.OPAPageID;  // 截取指令中的访问页号,来自MAR
                   if (ins.OPAPageID >=PAGE_NUMBER)
                   {
                            cout << "产生越界中断!" << endl;       // 应抛出异常?
                            return 1;
                   }
 
                   while(!pageTable[visitPageID].state)
                   {
                            cout << "产生缺页中断!" << endl;
                            Interrupt(pageTable,FIFOQueue, visitPageID);      // 缺页中断处理
 
                            // 须重复?
                            visitPageID =ins.OPAPageID; // 截取指令中的访问页号,来自MAR
                            if (visitPageID>= PAGE_NUMBER)
                            {
                                     cout<< "产生越界中断!" << endl;       // 应抛出异常?
                                     return 1;
                            }                          
                   }
 
                   unsigned visitBlockID =pageTable[visitPageID].blockID;
                   unsigned realAddr =visitBlockID * BLOCK_SIZE + ins.OPAUnitID;
                   cout << "绝对地址是" << realAddr <<endl;
                   if (ins.OPC == "存")
                   {
                            pageTable[visitPageID].modify= true;
                   }
                   cout << endl;
         }
 
         return 0;
}
 
/*cin.txt:
0 1 5 0111
1 1 8 0121
2 1 9 0130
3 1 10015 0
4 0 0 0170
5 0 0 0250
6 0 0 2120
7 0 0 2130
 
+ 0 040
+ 1 050
* 2 016
存 3 022
取 0 054
- 6 040
移位 4 052
+ 5 022
存 1 034
取 7 056
+ 4 002
取 6 076
*/

 

6、运行结果

执行指令1
绝对地址是360

执行指令2
绝对地址是562

执行指令3
绝对地址是592

执行指令4
绝对地址是662

执行指令5
绝对地址是374

执行指令6
产生缺页中断!
页0被修改过,写回磁盘
调页0到磁盘
调入页6
绝对地址是360

执行指令7
产生缺页中断!
页1被修改过,写回磁盘
调页1到磁盘
调入页4
绝对地址是564

执行指令8
产生缺页中断!
调页2到磁盘
调入页5
绝对地址是598

执行指令9
产生缺页中断!
页3被修改过,写回磁盘
调页3到磁盘
调入页1
绝对地址是674

执行指令10
产生缺页中断!
调页6到磁盘
调入页7
绝对地址是376

执行指令11
绝对地址是514

执行指令12
产生缺页中断!
调页4到磁盘
调入页6
绝对地址是588

请按任意键继续. . .


一. 实验目的: 1.通过编写和调试存储管理模拟程序以加深对存储管理方案的理解。熟悉虚存管理的各种页面淘汰算法 2.通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 二.实验要求 实验程序由以下三大部分组成: (1) 通过随机数产生一个指令序列(实际上是指令的逻辑地址序列),共320条指令。指令的地址按下述原则生成: A:50%的指令是顺序执行的 B:25%的指令要实现向前跳转,均匀分布在前地址部分 C:25%的指令要实现向后跳转,均匀分布在后地址部分 具体的实施方法是: A:在[0,319]的指令地址之间随机选取一起点m B:顺序执行一条指令,即执行地址为m+1的指令 C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’ D:顺序执行一条指令,其地址为m’+1 E:在后地址[m’+2,319]中随机选取一条指令并执行 F:重复步骤A-E,直到320次指令 (2) 将每条指令的逻辑地址变换为页地址 设:页面大小为1K; 用户内存容量4页到32页; 用户虚存容量为32K。 在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为: 第 0 条-第 9 条指令为第0页(对应逻辑地址为[0,9]) 第10条-第19条指令为第1页(对应逻辑地址为[10,19]) ……………………………… 第310条-第319条指令为第31页(对应逻辑地址为[310,319]) 按以上方式,用户指令可组成32页。 (3) 分别使用FIFO算法和LFU算法,计算给用户进程的这32页分配4,5,…,32个页面(内存块)时其缺页率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值