【实验目的】
1.掌握分页式存储管理地址转换和缺页中断。
2.理解虚拟存储器概念。
【实验内容】
模拟分页式存储管理中硬件的地址转换:利用进制来模拟地址转换
【实验步骤】
1.数据结构
long lo_addr;//逻辑地址
long ph_addr;//物理地址
long pagelist[PNUM];
void init_ex1()
{
//左边的角标是页号,右边的值是页号对应的块号
pagelist[0] = 6;
pagelist[1] = 5;
pagelist[2] = 7;
pagelist[3] = 8;
pagelist[4] = 9;
pagelist[5] = 1;
pagelist[6] = 3;
pagelist[7] = 2;
pagelist[8] = 4;
pagelist[9] = 10;
pagelist[10] = 0;
pagelist[11] = 18;
pagelist[12] = 16;
pagelist[13] = 14;
}
void work_ex1()//模拟分页式存储管理中硬件的地址转换和产生缺页中断过程
2.程序流程图
3.实验代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PNUM 10//页号总数
#define PSIZE 4096//页大小
long lo_addr;//逻辑地址
long ph_addr;//物理地址
long pagelist[PNUM];
void init_ex1()
{
//左边的角标是页号,右边的值是页号对应的块号
pagelist[0] = 6;
pagelist[1] = 5;
pagelist[2] = 7;
pagelist[3] = 8;
pagelist[4] = 9;
pagelist[5] = 1;
pagelist[6] = 3;
pagelist[7] = 2;
pagelist[8] = 4;
pagelist[9] = 10;
pagelist[10] = 0;
pagelist[11] = 18;
pagelist[12] = 16;
pagelist[13] = 14;
}
void work_ex1()//模拟分页式存储管理中硬件的地址转换和产生缺页中断过程
{
int stop = 0;
int flag = 0;
//int len = log(2,PSIZE);
long p = 0;//页号
long w = 0;//页内地址
char s[128];
do
{
int i,j;
printf("**************【当前页号与块号的对应关系如下:】**************\n");
printf("页号 块号 (页大小:%d)\n", PSIZE);
for(i = 0;i < PNUM;i++)
printf(" %-10d%ld\n", i, pagelist[i]);
printf("现在您可以输入一个16进制的地址:");
flag = scanf("%x", &lo_addr);
if(flag != 1)
{
fflush(stdin);
printf("如果您不想继续,请输入exit,否则将继续!\n");
flag = scanf("%s",s);
if(strcmp(s,"exit")==0)
{//如果输入的为"exit"那么就退出,进入重选页面
stop = 1;
}
}
else
{
char p_Str[128], w_Str[128];
//1.如何将一个地址变为二进制。
itoa(lo_addr, s, 2);//将16进制的逻辑地址转为二进制数的字符串形式存到s中
int PSIZE_bitLen = log2(PSIZE);//记录页大小用二进制表示时所需的位数
//2.再将二进制变为字符串,拆分为两个字符串?
for(i = 0;i < strlen(s);i++)
{
if(i < strlen(s) - PSIZE_bitLen)
p_Str[i] = s[i];//页号的二进制字符串形式
else
{
if(i == strlen(s) - PSIZE_bitLen)
p_Str[i] = '\0';//给p_Str数组加结束符
w_Str[i-(strlen(s)-PSIZE_bitLen)] = s[i];//页内大小的二进制字符串形式
}
}
w_Str[i-(strlen(s)-PSIZE_bitLen)] = '\0';//给w_Str数组加结束符
//3.将高位字符串先变为整型(10进制)页号。
char * endptr;
p = strtol(p_Str, &endptr, 2);//将字符串形式的二进制页号转为long型
printf("\n该地址的页号为:%d,用二进制表示为:%s\n", p, p_Str);
//4.查页表,将页号对应的块号求出来;
printf("该地址对应的块号为:%ld,", pagelist[p]);
//5.将块号变为二进制;
//6.将二进制变为字符串;
char blockNum_BinaryStr[128];
itoa(pagelist[p], blockNum_BinaryStr, 2);//进十进制形式下的块号转为二进制
printf("用二进制表示为:%s\n\n", blockNum_BinaryStr);//输出二进制形式下的块号
//7.将该字符串与低位字符串合并;
strcat(blockNum_BinaryStr, w_Str);
printf("偏移量(页内地址)为:%s\n", w_Str);
printf("块号与偏移量重新组合后为:%s\n\n", blockNum_BinaryStr);
//8.将新的字符串变为整数(二进制);
ph_addr = strtol(blockNum_BinaryStr, &endptr, 2);//将拼接好的字符串转为二进制整数
//9.将该数用16进制形式输出,就是物理地址;
printf("您输入的16进制逻辑地址为:%X,其对应的物理地址为:%X\n\n", lo_addr, ph_addr);
}
}
while(!stop);
}
int main()
{
init_ex1();
work_ex1();
return 0;
}