#include "stdio.h"
#define n 64 /*模拟實驗中假定的頁表長度,即最多允許程式含有多少頁;假定頁面大小為1K*/
#define length 10
struct
{
int lnumber;/*頁号*/
int flag; /*表示該頁是否在主存,"1"表示在主存中,"0"表示不在*/
int pnumber;/*該頁所在主存塊的塊号*/
int write; /*該頁是否被修改過,"1"表示修改過,"0"表示沒有修改過*/
int dnumber;/*該頁存放在磁盤上的位置,即磁盤塊号*/
}page[n]; /*頁表定義*/
int m; /*m為該作業在主存中的主存塊塊數*/
int page_length;/*頁表實際長度*/
int p[length]; /*存放在主存中的頁的頁号*/
int head; /*主存中頁号隊列,指向下次要被替換的頁号*/
void page_interrupt(int lnumber) /*缺頁中斷處理函數,采用FIFO頁面置換算法*/
{
int j;
printf("發生缺頁中斷* %d\n",lnumber);
/*淘汰頁*/
j=p[head];
p[head]=lnumber;/* 裝入替換後的新頁号*/
head=(head+1)%m;
if (page[j].write==1)
printf("将頁 %d寫回磁盤第%d塊\n",j,page[j].dnumber);
/*修改頁表*/
page[j].flag=0;/* 第j頁被換出,第j頁存在标志改為"0"*/
page[lnumber].pnumber=page[j].pnumber;/* 第lnumber頁裝入原來第j頁所在的實體塊*/
page[lnumber].flag=1;/* 第lnumber頁存在标志改為"1"*/
page[lnumber].write=0;/* 第lunmber頁修改标志改為"0"*/
printf("淘汰主存塊%2d中的頁%2d,從磁盤第%d塊中調入頁%2d\n", page[j].pnumber,j,page[lnumber].dnumber,lnumber);
}/*缺頁中斷處理函數結束*/
void command(unsigned laddress,int write) /*指令處理函數*/
{
unsigned paddress,ad,pnumber;//分别存放實體位址、頁内位址和外存位址(盤塊号);
int lnumber;//存放頁号;
lnumber=laddress>>10;//頁号=邏輯位址/2^10 /*先計算出頁号(高6位)和頁内位址(低10位);*/
ad=laddress%0x3ff;//頁内位址利用位運算來取出後10位
kk:
if(lnumber>=page_length) /*判斷頁号是否越界,若越界,顯示越界不再進行位址變換;*/
{
printf("不存在該頁\n");
return;
}
if(page[lnumber].flag==1) /*若通路的頁在記憶體,查找對應的實體塊,計算實體位址;若不在記憶體,先調用page_interrupt(int lnumber)進行頁面置換,再進行位址變換。*/
{
pnumber=page[lnumber].pnumber;
paddress=pnumber<<10|ad;
printf("邏輯位址是:%d,對應實體位址是:%d\n",laddress,paddress);
if(write==1)
page[lnumber].write=1;
}
else
{
page_interrupt(lnumber);
goto kk;
}
}
/*指令處理函數結束*/
void main( )
{
int lnumber,flag,pnumber,write,dnumber;
unsigned laddress;
int i;
/*輸入頁表的資訊,頁号從0開始,依次編号,建立頁表page*/
printf("輸入頁表的資訊,建立頁表(若頁号為-1,則結束輸入))\n");
//printf("輸入頁号和輔存位址:");
//scanf("%d%d",&lnumber,&dnumber);
i=0;
do
{
printf("輸入頁号和輔存位址:");
scanf("%d%d",&lnumber,&dnumber);
page[i].lnumber=lnumber;
page[i].flag=0;
page[i].write=0;
page[i].dnumber=dnumber;
i++;
}while(lnumber!=-1);
page_length=i-1;//因為多輸入了一個-1;
printf("輸入主存塊号,主存塊數要小于%d,(以-1結束):",i-1);
scanf("%d",&pnumber);
m=0;
head=0;
while(pnumber!=-1)
{
if(m<=i)
{
page[m].pnumber=pnumber;
page[m].flag=1;
p[m]=m;//對數組P進行初始化,一開始程式的前m+1頁調入記憶體
m++;
}
scanf("%d",&pnumber);
}
printf("輸入指令性質(1-修改,0-不需要,其他-結束程式運作)和邏輯位址:");
scanf("%d%u",&write,&laddress);
while(write==0||write==1)
{
command(laddress,write);/* 執行指令*/
printf("輸入指令性質(1-修改,0-不需要,其他-結束程式運作)和邏輯位址:");
scanf("%d%u",&write,&laddress);
}
}/*main( )函數結束*/