作業系統 頁式虛擬儲存地址變換
阿新 • • 發佈:2019-02-11
#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( )函式結束*/