算法思想:
- 請求分頁虛擬存儲管理技術,是把作業地址空間的全部信息存放在磁盤上。當作業被選中運行時,先把作業的開始幾頁裝入主存,並啓動運行。爲此,在爲作業建立頁表時,應說明哪些頁已在主存,哪些頁不在主存。其中標誌表示對應頁是否已經裝入主存。1表示對應頁已經裝入主存;0表示對應頁未裝入主存;主存塊號表示該頁對應的主存塊號;修改位指示該頁調入主存後是否修改過的標誌;外存地址指示該頁所在的外存地址。
- 作業執行時,指令中的邏輯地址指出參加運算的操作數(或指令)地址中的頁號和頁內偏移量。硬件地址轉換機構按頁號查頁表。若該頁的標誌爲1,則表示該頁已在主存,從而找到該頁對應的主存塊號。計算關係式,絕對地址等於塊號*塊的長度+頁內偏移量。計算出預訪問的主存地址。由於頁長爲2的整次冪。所以只要將塊號和頁內偏移量相拼接。放入主存地址寄存器即可。按照該地址取指令或取操作數,完成指定的操作。
- 設計一個地址變換程序,模擬硬件地址變換過程,當訪問的頁在主存時,則形成絕對地址後,不去模擬指令的執行,而是輸出被轉換的地址,當訪問的頁不在主存時,則輸出該頁不在主存,產生缺頁中斷,以表示產生了一次缺頁中斷。
進行缺頁中斷處理,中斷返回後,重新執行該指令。假定主存的每塊長度爲64個字節,現有一個具有8頁的作業系統,爲其分配的4個主存塊(即m=4),且最多分四塊。其中第0頁至第3頁已經裝入主存。
(4)當採用LRU算法時。則淘汰最近很少訪問的頁。
代碼:
#include<iostream>
#include<vector>
#include<list>
#include<string>
using namespace std;
typedef struct pageTable{
int pageNumber;
int sign=0;
int mainStorageBlockNumber;
int modifiedBit=0;
int externalAddress;
}pageTable;
typedef struct instructionTable{
string operation;
int pageNumber;
int unitNumber;
}instructionTable;
void initPageTable(vector<pageTable>&p){
int pageNumber[]={0,1,2,3,4,5,6,7};
int sign[]={1,1,1,1,0,0,0,0};
int mainStorageBlockNumber[]={5,8,9,10,-1,-1,-1,-1};
int modifiedBit[]={1,1,0,0,-1,-1,-1,-1};
int externalAddress[]={11,12,13,15,17,025,212,213};
pageTable s;
for(int i=0;i<8;i++){
s.pageNumber=pageNumber[i];
s.sign=sign[i];
s.mainStorageBlockNumber=mainStorageBlockNumber[i];
s.modifiedBit=modifiedBit[i];
s.externalAddress=externalAddress[i];
p.push_back(s);
}
}
void initInstructionTable(vector<instructionTable>&p){
string operation[]={"+","+","*","存","取","-","移位","+","存","取","+","取"};
int pageNumber[]={0,1,2,3,0,6,4,5,1,7,4,6};
int unitNumber[]={40,50,16,22,54,40,52,22,34,56,2,76};
instructionTable s;
for(int i=0;i<12;i++){
s.operation=operation[i];
s.pageNumber=pageNumber[i];
s.unitNumber=unitNumber[i];
p.push_back(s);
}
}
void printPageTable(vector<pageTable>p){
cout<<"頁表中的內容如下:"<<endl;
cout<<"頁號\t"<<"標誌\t"<<"主存塊號\t"<<"外存地址\t"<<"修改位"<<endl;
for(vector<pageTable>::iterator it=p.begin();it!=p.end();it++){
cout<<it->pageNumber<<"\t"<<it->sign<<"\t"<<it->mainStorageBlockNumber<<"\t\t"<<it->externalAddress<<"\t\t"<<it->modifiedBit<<endl;
}
}
void printInstructionTable(vector<instructionTable>p){
cout<<"指令表的內容如下:"<<endl;
cout<<"操作\t"<<"頁號\t"<<"單元號"<<endl;
for(vector<instructionTable>::iterator it=p.begin();it!=p.end();it++)
cout<<it->operation<<"\t"<<it->pageNumber<<"\t"<<it->unitNumber<<endl;
cout<<endl;
}
void addressTranform(vector<pageTable>&p,vector<instructionTable>&q){
int absoluteAddress;
vector<int>l;
bool flag;
for(vector<instructionTable>::iterator it=q.begin();it!=q.end();it++){
cout<<"當前指令:"<<endl;
cout<<"操作\t"<<"頁號\t"<<"單元號"<<endl;
cout<<it->operation<<"\t"<<it->pageNumber<<"\t"<<it->unitNumber<<endl;
vector<pageTable>::iterator it2;
for(it2=p.begin();it2!=p.end();it2++)
if(it->pageNumber==it2->pageNumber)
break;
if(it2->sign==1){
absoluteAddress=it2->mainStorageBlockNumber*64+it->unitNumber;
cout<<"絕對地址:"<<absoluteAddress<<endl;
if(it->operation=="存")
it2->modifiedBit=1;
flag=true;
for(vector<int>::iterator it3=l.begin();it3!=l.end();it3++)
if(it->pageNumber==*it3){
l.erase(it3);
l.insert(l.begin(),it->pageNumber);
flag=false;
break;
}
if(flag){
if(l.size()<4)
l.insert(l.begin(),it->pageNumber);
else{
l.pop_back();
l.insert(l.begin(),it->pageNumber);
}
}
}
else{
cout<<"該頁不在主存,產生缺頁中斷"<<endl;
int t=l.back();
l.pop_back();
l.insert(l.begin(),it->pageNumber);
vector<pageTable>::iterator i;
for(i=p.begin();i!=p.end();i++)
if(i->pageNumber==t){
i->sign=0;
i->modifiedBit=-1;
it2->sign=1;
it2->mainStorageBlockNumber=i->mainStorageBlockNumber;
i->mainStorageBlockNumber=-1;
break;
}
absoluteAddress=it2->mainStorageBlockNumber*64+it->unitNumber;
cout<<"絕對地址:"<<absoluteAddress<<endl;
}
printPageTable(p);
cout<<"棧中的序列:";
for(vector<int>::iterator i=l.begin();i!=l.end();i++)
cout<<*i<<"";
cout<<endl<<endl<<endl;
}
}
int main(){
vector<pageTable>p;
vector<instructionTable>q;
cout<<"初始化頁表和指令表:"<<endl;
initPageTable(p);
printPageTable(p);
initInstructionTable(q);
printInstructionTable(q);
addressTranform(p,q);
getchar();
getchar();
return 0;
}
結果: