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
请按任意键继续. . .