第一篇:虛存管理OS實驗[推薦]
實驗三 虛存管理
一、實驗?zāi)康?/p>
1.加深對存儲管理概念的理解。
2.深入了解Windows內(nèi)存管理機制。
3.理解內(nèi)存分配原理,特別是以頁面為單位的虛擬內(nèi)存分配方法。4.掌握頁式虛擬存儲技術(shù)。
5.掌握“最不頻繁使用淘汰算法”,即LFU頁面淘汰算法。
二、理論基礎(chǔ)
1.頁式存儲管理技術(shù)。2.虛擬存儲管理技術(shù)。
三、實驗要求
1.編寫程序?qū)崿F(xiàn)簡單的虛存管理。
2.實驗具體包括:(1)設(shè)計并實現(xiàn)一個虛存管理程序,模擬一個單道程序的頁式存儲管理,用一個一維數(shù)組模擬實存空間,用一個文本文件模擬輔存空間;(2)建立一張一級頁表;
(3)編寫函數(shù)隨機產(chǎn)生訪存請求,訪存操作包括讀取、寫入、執(zhí)行等三種類型;(4)編寫函數(shù)響應(yīng)訪存請求,完成虛地址到實地址的定位及讀/寫/執(zhí)行操作,同時判斷并處理缺頁中斷;(5)實現(xiàn)LFU頁面淘汰算法。3.實驗結(jié)束提交書面實驗報告。
四、實驗環(huán)境
1.運行Windows操作系統(tǒng)的PC機一臺。
2.PC機上安裝Visual C++ 6.0開發(fā)工具軟件。
五、實驗內(nèi)容
1.2.3.4.建立“Win32 Console Application”工程“vmm”。建立“C/C++ Header File”頭文件“vmm.h”,文件內(nèi)容參見“程序代碼”。建立“C++ Source File”源文件“vmm.cpp”,文件內(nèi)容參見“程序代碼”。建立“Text File”文本文件“vmm_auxMem.txt”,模擬輔存空間,文件內(nèi)容可以輸入任意字符(字符數(shù)多于512個)。
5.運行程序并認真觀察和分析程序的運行結(jié)果。
七、程序代碼
頭文件“vmm.h” #ifndef VMM_H #define VMM_H
/* 模擬輔存的文件路徑 */ #define AUXILIARY_MEMORY “vmm_auxMem.txt”
/* 頁面大小(字節(jié))*/
#define PAGE_SIZE 4 /* 虛存空間大?。ㄗ止?jié))*/ #define VIRTUAL_MEMORY_SIZE(64 * 4)/* 實存空間大?。ㄗ止?jié))*/
#define ACTUAL_MEMORY_SIZE(32 * 4)/* 總虛頁數(shù) */ #define PAGE_SUM(VIRTUAL_MEMORY_SIZE / PAGE_SIZE)/* 總物理塊數(shù) */ #define BLOCK_SUM(ACTUAL_MEMORY_SIZE / PAGE_SIZE)
/* 可讀標識位 */ #define READABLE 0x01u /* 可寫標識位 */ #define WRITABLE 0x02u /* 可執(zhí)行標識位 */ #define EXECUTABLE 0x04u
/* 頁表項 */ typedef struct { unsigned int blockNum;//物理塊號
BOOL filled;//頁面裝入特征位
BYTE proType;//頁面保護類型
BOOL edited;//頁面修改標識
unsigned long auxAddr;//外存地址 unsigned long count;//頁面使用計數(shù)器
} PageTableItem, *Ptr_PageTableItem;
/* 訪存請求類型 */ typedef enum {
REQUEST_READ, REQUEST_WRITE,REQUEST_EXECUTE } MemoryAccessRequestType;
/* 訪存請求 */ typedef struct { MemoryAccessRequestType reqType;//訪存請求類型
unsigned long virAddr;//虛地址 BYTE value;//寫請求的值
} MemoryAccessRequest, *Ptr_MemoryAccessRequest;
/* 訪存錯誤代碼 */
typedef enum { ERROR_READ_DENY, //該頁不可讀
ERROR_WRITE_DENY, //該頁不可寫
ERROR_EXECUTE_DENY, //該頁不可執(zhí)行
ERROR_INVALID_REQUEST, //非法請求類型
ERROR_OVER_BOUNDARY, //地址越界
ERROR_FILE_OPEN_FAILED, //文件打開失敗 ERROR_FILE_CLOSE_FAILED, //文件關(guān)閉失敗 ERROR_FILE_SEEK_FAILED, //文件指針定位失敗 ERROR_FILE_READ_FAILED, //文件讀取失敗 ERROR_FILE_WRITE_FAILED //文件寫入失敗
} ERROR_CODE;
/* 產(chǎn)生訪存請求 */ void do_request();/* 響應(yīng)訪存請求 */ void do_response();/* 處理缺頁中斷 */ void do_page_fault(Ptr_PageTableItem);/* LFU頁面替換 */ void do_LFU(Ptr_PageTableItem);/* 裝入頁面 */ void do_page_in(Ptr_PageTableItem, unsigned int);/* 寫出頁面 */ void do_page_out(Ptr_PageTableItem);/* 錯誤處理 */ void do_error(ERROR_CODE);/* 打印頁表相關(guān)信息 */ void do_print_info();/* 獲取頁面保護類型字符串 */ char *get_proType_str(char *, BYTE);#endif
源文件“vmm.cpp” #include
/* 頁表 */ PageTableItem pageTable[PAGE_SUM];/* 實存空間 */
BYTE actMem[ACTUAL_MEMORY_SIZE];/* 用文件模擬輔存空間 */ FILE *ptr_auxMem;/* 物理塊使用標識 */ bool blockStatus[BLOCK_SUM];/* 訪存請求 */ Ptr_MemoryAccessRequest ptr_memAccReq;
/* 初始化環(huán)境 */ void do_init(){
srand((unsigned int)time(NULL));for(int i = 0;i < PAGE_SUM;i++){
pageTable[i].filled = false;pageTable[i].edited = false;pageTable[i].count = 0;/* 使用隨機數(shù)設(shè)置該頁的保護類型 */ switch(rand()% 7){
case 0: { pageTable[i].proType = READABLE;break;} case 1: { pageTable[i].proType = WRITABLE;break;} case 2: {
} {
} case 4: { pageTable[i].proType = READABLE | EXECUTABLE;pageTable[i].proType = EXECUTABLE;break;case 3:
pageTable[i].proType = READABLE | WRITABLE;break;
break;} case 5: { pageTable[i].proType = WRITABLE | EXECUTABLE;
} case 6: {
} pageTable[i].proType = READABLE | WRITABLE | EXECUTABLE;break;break;default: break;
} /* 設(shè)置該頁對應(yīng)的輔存地址,本程序為實現(xiàn)簡單采用順序設(shè)置的方式,可替換成其他設(shè)置方式,但須注意每個頁表項對應(yīng)的輔存地址均應(yīng)為PAGE_SIZE的整數(shù)倍 */
}
/* 響應(yīng)請求 */ void do_response(){
} {
} pageTable[i].auxAddr = i * PAGE_SIZE * 2;for(int j = 0;j < BLOCK_SUM;j++)/* 隨機選擇一些物理塊進行頁面裝入 */ if(rand()% 2 == 0){ do_page_in(&pageTable[j], j);pageTable[j].blockNum = j;pageTable[j].filled = true;blockStatus[j] = true;} else blockStatus[j] = false;Ptr_PageTableItem ptr_pageTabIt;unsigned int pageNum, offAddr;unsigned int actAddr;
/* 檢查地址是否越界 */ if(ptr_memAccReq->virAddr < 0 ||
{
} ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)do_error(ERROR_OVER_BOUNDARY);return;
/* 計算頁號和頁內(nèi)偏移值 */ pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;printf(“頁號為:%ut頁內(nèi)偏移為:%un”, pageNum, offAddr);/* 獲取對應(yīng)頁表項 */ ptr_pageTabIt = &pageTable[pageNum];
/* 根據(jù)特征位決定是否產(chǎn)生缺頁中斷 */ if(!ptr_pageTabIt->filled){ }
actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;printf(“實地址為:%un”, actAddr);
/* 檢查頁面訪問權(quán)限并處理訪存請求 */ switch(ptr_memAccReq->reqType){
case REQUEST_READ: //讀請求 {
ptr_pageTabIt->count++;if(!(ptr_pageTabIt->proType & READABLE))//頁面不可讀 { do_error(ERROR_READ_DENY);do_page_fault(ptr_pageTabIt);return;} /* 讀取實存中的內(nèi)容 */ printf(“讀操作成功:值為%02Xn”, actMem[actAddr]);break;} case REQUEST_WRITE: //寫請求 {
ptr_pageTabIt->count++;if(!(ptr_pageTabIt->proType & WRITABLE))//頁面不可寫 { do_error(ERROR_WRITE_DENY);
}
return;} /* 向?qū)嵈嬷袑懭胝埱蟮膬?nèi)容 */ actMem[actAddr] = ptr_memAccReq->value;ptr_pageTabIt->edited = true;
printf(“寫操作成功n”);break;} case REQUEST_EXECUTE: //執(zhí)行請求 {
ptr_pageTabIt->count++;if(!(ptr_pageTabIt->proType & EXECUTABLE))//頁面不可執(zhí)行 { do_error(ERROR_EXECUTE_DENY);return;}
printf(“執(zhí)行成功n”);break;} default: //非法請求類型 {
}
do_error(ERROR_INVALID_REQUEST);return;}
/* 處理缺頁中斷 */ void do_page_fault(Ptr_PageTableItem ptr_pageTabIt){ printf(“產(chǎn)生缺頁中斷,開始進行調(diào)頁...n”);
for(unsigned int i = 0;i < BLOCK_SUM;i++){
if(!blockStatus[i]){
/* 讀輔存內(nèi)容,寫入到實存 */ do_page_in(ptr_pageTabIt, i);
/* 更新頁表內(nèi)容 */ ptr_pageTabIt->blockNum = i;ptr_pageTabIt->filled = true;ptr_pageTabIt->edited = false;ptr_pageTabIt->count = 0;
}
blockStatus[i] = true;
return;} } /* 沒有空閑物理塊,進行頁面替換 */ do_LFU(ptr_pageTabIt);
/* 根據(jù)LFU算法進行頁面替換 */ void do_LFU(Ptr_PageTableItem ptr_pageTabIt){
}
/* 將輔存內(nèi)容寫入實存 */ void do_page_in(Ptr_PageTableItem ptr_pageTabIt, unsigned int blockNum)printf(“沒有空閑物理塊,開始進行LFU頁面替換...n”);for(unsigned int i = 0, min = 0xFFFFFFFF, page = 0;i < PAGE_SUM;i++){
if(pageTable[i].count < min){
} min = pageTable[i].count;page = i;} printf(“選擇第%u頁進行替換n”, page);if(pageTable[page].edited){ /* 頁面內(nèi)容有修改,需要寫回至輔存 */ printf(“該頁內(nèi)容有修改,寫回至輔存n”);} do_page_out(&pageTable[page]);pageTable[page].filled = false;pageTable[page].count = 0;/* 讀輔存內(nèi)容,寫入到實存 */ do_page_in(ptr_pageTabIt, pageTable[page].blockNum);
/* 更新頁表內(nèi)容 */ ptr_pageTabIt->blockNum = pageTable[page].blockNum;ptr_pageTabIt->filled = true;ptr_pageTabIt->edited = false;ptr_pageTabIt->count = 0;printf(“頁面替換成功n”);
{
unsigned int readNum;if(fseek(ptr_auxMem, ptr_pageTabIt->auxAddr, SEEK_SET)< 0){ exit(1);} if((readNum = fread(actMem + blockNum * PAGE_SIZE,{ sizeof(BYTE), PAGE_SIZE, ptr_auxMem))< PAGE_SIZE)exit(1);} printf(“調(diào)頁成功:輔存地址%u-->>物理塊%un”, ptr_pageTabIt->auxAddr, blockNum);}
/* 將被替換頁面的內(nèi)容寫回輔存 */ void do_page_out(Ptr_PageTableItem ptr_pageTabIt){ unsigned int writeNum;
} if(fseek(ptr_auxMem, ptr_pageTabIt->auxAddr, SEEK_SET)< 0){ exit(1);} if((writeNum = fwrite(actMem + ptr_pageTabIt->blockNum * PAGE_SIZE,sizeof(BYTE), PAGE_SIZE, ptr_auxMem))< PAGE_SIZE){ do_error(ERROR_FILE_WRITE_FAILED);exit(1);} printf(“寫回成功:物理塊%u-->>輔存地址%un”, ptr_pageTabIt->auxAddr, ptr_pageTabIt->blockNum);
/* 錯誤處理 */ void do_error(ERROR_CODE code){
switch(code){
case ERROR_READ_DENY: { printf(“訪存失?。涸摰刂穬?nèi)容不可讀n”);break;} case ERROR_WRITE_DENY:
{ printf(“訪存失敗:該地址內(nèi)容不可寫n”);break;} case ERROR_EXECUTE_DENY: {
} {
} printf(“訪存失?。涸摰刂穬?nèi)容不可執(zhí)行n”);break;
case ERROR_INVALID_REQUEST: printf(“訪存失?。悍欠ㄔL存請求n”);break;case ERROR_OVER_BOUNDARY: { printf(“訪存失?。旱刂吩浇鏽”);} { break;case ERROR_FILE_OPEN_FAILED: printf(“系統(tǒng)錯誤:打開文件失敗n”);break;} case ERROR_FILE_CLOSE_FAILED: { printf(“系統(tǒng)錯誤:關(guān)閉文件失敗n”);break;} case ERROR_FILE_SEEK_FAILED: {
} printf(“系統(tǒng)錯誤:文件指針定位失敗n”);break;case ERROR_FILE_READ_FAILED: { printf(“系統(tǒng)錯誤:讀取文件失敗n”);} {
} break;case ERROR_FILE_WRITE_FAILED: printf(“系統(tǒng)錯誤:寫入文件失敗n”);break;
}
} default: { } printf(“未知錯誤:沒有這個錯誤代碼n”);
/* 產(chǎn)生訪存請求 */ void do_request(){
}
/* 打印頁表 */ void do_print_info(){ /* 隨機產(chǎn)生請求地址 */ ptr_memAccReq->virAddr = rand()% VIRTUAL_MEMORY_SIZE;/* 隨機產(chǎn)生請求類型 */ switch(rand()% 3){
} case 0: //讀請求 {
ptr_memAccReq->reqType = REQUEST_READ;printf(“產(chǎn)生請求:n地址:%ut類型:讀取n”, ptr_memAccReq->virAddr);break;} case 1: //寫請求 {
} ptr_memAccReq->reqType = REQUEST_WRITE;/* 隨機產(chǎn)生待寫入的值 */ ptr_memAccReq->value = rand()% 0xFFu;printf(“產(chǎn)生請求:n地址:%ut類型:寫入t值:%02Xn”,ptr_memAccReq->virAddr, ptr_memAccReq->value);break;case 2: {
} ptr_memAccReq->reqType = REQUEST_EXECUTE;printf(“產(chǎn)生請求:n地址:%ut類型:執(zhí)行n”, ptr_memAccReq->virAddr);break;default: break;
} char str[4];printf(“頁號t塊號t裝入t修改t保護t計數(shù)t輔存n”);for(unsigned int i = 0;i < PAGE_SUM;i++){ printf(“%ut%ut%ut%ut%st%ut%un”, i,}
pageTable[i].blockNum, pageTable[i].filled,pageTable[i].edited, get_proType_str(str, pageTable[i].proType), pageTable[i].count, pageTable[i].auxAddr);
/* 獲取頁面保護類型字符串 */ char *get_proType_str(char *str, BYTE type){
} if(type & READABLE)str[0] = 'r';else str[0] = '-';if(type & WRITABLE)else str[1] = '-';if(type & EXECUTABLE)str[2] = 'x';else str[2] = '-';str[3] = ' 主站蜘蛛池模板: 精品人妻无码视频中文字幕一区二区三区| 开心婷婷五月激情综合社区| 女人又爽?又黄?免费俄罗斯| 国产精品亚洲αv天堂| 国产超碰女人任你爽| 无码国产精品久久一区免费| 欧美40老熟妇色xxxxx| 熟妇人妻av中文字幕老熟妇| 欧美在线三级艳情网站| 国产日产亚洲系列最新| 国精一二二产品无人区免费应用| 亚洲午夜爱爱香蕉片| 国产视频一区二区| 久久www免费人成—看片| 国产精品自在自线视频| 日韩精品人妻系列一区二区三区| 无码h肉男男在线观看免费| 国产av人人夜夜澡人人爽麻豆| 精品国产污污免费网站入口| 97超碰国产精品最新| 精品一区二区三区国产在线观看| 亚洲熟妇无码久久精品| 亚洲成av人在线视| 蜜桃麻豆www久久囤产精品| 特黄aaaaaaaaa毛片免费视频| 国产欧美在线一区二区三| 精品乱码久久久久久中文字幕| 国产精品一区二区av蜜芽| 亚洲精品久久久久久久蜜臀老牛| 日本一卡二卡四卡无卡乱码视频免费| 久久不见久久见www电影免费| 国产旡码高清一区二区三区| 国产精品视频第一区二区三区| 国产精品嫩草影院免费观看| 国产人妻精品区一区二区三区| 亚洲老子午夜电影理论| 久青草久青草视频在线观看| 性一交一乱一色一视频| 少妇愉情理伦片丰满丰满| 97se亚洲国产综合自在线| 亚洲成av人片无码bt种子下载|