目的:了解分页存储管理方式的原理和实现的基本过程。
设计要求:设计一个简单分页存储管理系统,要求实现以下功能。
(1) 定义分页的地址结构和页表结构。
(2) 对进程的逻辑地址空间、页表起址、给定的逻辑地址进行初始化。
(3) 实现从逻辑地址到物理地址的变换。
(4) 实现“主存空间的共享和保护”功能。
(5) 实现“主存扩充”虚拟功能。
C++源码如下(编译环境:Mingw-w64/gcc 8.1.0):
//物理块:4KB; 物理块数:256;共享状态:1共享,0不共享;访问状态:1访问过,0未访问过
#include
#include
#include
#include
#include
using namespace std;
int init(); //初始化
int show_Share_Page(); //展示共享页表
int t = 1;
int p = -1; //clock算法指针
int q = 0;
int c = 0;
int ram_block_state[256]; //物理块分配状态
struct Pages_item { //页表项
int pages_num;
int ram_block_num;
int share_state; //1共享,0不共享
int position_state;//1在内存,0不在内存
int visit;//1最近被访问;0最近未被访问
};
struct share_page_item //共享页表项
{
int pro_id;
int pages_num;
int share_state;
};
vector<share_page_item> Share_Page; //共享页表
class PCB
{
int id;
int page_item_sum;
int ram_block[5];
vector<Pages_item> Page;
public:
PCB();
int show(); //展示页表
int inquiry(); //输入逻辑地址,并转化为物理地址
int clock(); //置换算法;
};
PCB::PCB()
{
id = t++;
int r = 0;
srand(time(0));
//分配进程物理块
for (int i = 0; i < 5; i++)
{
while (1)
{
int a = 0;
ram_block[i] = rand() % 0xff + 1;
if (ram_block_state[ram_block[i]] == 0)
{
ram_block_state[ram_block[i]] = 1;
break;
}
else
a++;
if (a == 256)
{
cout << "物理内存不足,无法分配\n";
system("pause");
exit(0);
}
}
for (int j = 0; j < i; j++)
{
if (ram_block[i] == ram_block[j])
{
r = 1;
break;
}
}
if (r == 1)
{
r = 0;
i--;
}
}
//分配进程页数
page_item_sum = rand() % 10 + 3;
for (int i = 0; i < page_item_sum; i++)
{
Pages_item a;
a.pages_num = i + 1;
if (i < 5)
a.ram_block_num = i;
else
a.ram_block_num = 10000;//为分配物理块
a.share_state = rand() % 2;
if (a.ram_block_num == 10000)
a.position_state = 0;
else
a.position_state = 1;
a.visit = 0;
Page.push_back(a);
share_page_item b;
//将共享页加入共享页表
if (a.share_state == 1)
{
b.pro_id = id;
b.pages_num = a.pages_num;
b.share_state = a.share_state;
Share_Page.push_back(b);
}
}
}
int PCB::show()
{
cout << id << "进程的页表为:\n";
cout << "页号\t" << "物理块号\t" << "共享状态\t" << "存储状态\t" << "访问位\n";
for (int i = 0; i < page_item_sum; i++)
if (Page[i].position_state == 1)
cout << setiosflags(ios::uppercase) << hex << Page[i].pages_num
<< "\t" << ram_block[Page[i].ram_block_num] << "\t\t" << Page[i].share_state
<< "\t\t" << Page[i].position_state << "\t\t" << Page[i].visit << endl;
else
{
cout << setiosflags(ios::uppercase) << hex << Page[i].pages_num
<< "\t\t\t" << Page[i].share_state << "\t\t" << Page[i].position_state << "\t\t"
<< Page[i].visit << endl;
}
cout << endl;
return 0;
}
int PCB::inquiry()
{
cout << "请输入逻辑地址(5位十六进制地址): ";
int a, page_num, pagein_address, ram_block_, b = 0, physics_address;
while (!(cin >> hex >> a) || a < 0x1000)
{
cin.clear();
cin.sync();
cout << "地址格式输入错误,请重新输入!\n"
<< "请输入逻辑地址(5位十六进制地址): ";
}
page_num = a / 0x1000;
pagein_address = a % 0x1000;
for (int i = 0; i < page_item_sum; i++)
if (Page[i].pages_num == page_num)
{
b = 1;
if (Page[i].position_state == 0)
{
int a = clock(); //选择出要置换的页面
int t = Page[a].ram_block_num;
Page[a].ram_block_num = Page[i].ram_block_num;
Page[i].ram_block_num = t;
Page[i].position_state = 1;
Page[a].position_state = 0;
}
ram_block_ = ram_block[Page[i].ram_block_num];
Page[i].visit = 1;
break;
}
if (b == 0)
{
cout << "输入错误,地址越界!\n";
system("pause");
exit(0);
}
physics_address = ram_block_ * 0x1000 + pagein_address;
cout << "物理地址为:" << setiosflags(ios::uppercase) << hex << physics_address << endl << endl;
return 0;
}
int PCB::clock()
{
p = ++p % page_item_sum;
for (; p < page_item_sum; p++)
if (Page[p].visit == 1)
Page[p].visit = 0;
else
break;
return p;
}
int init()
{
for (int i = 0; i < 256; i++)
ram_block_state[i] = 0;
return 0;
}
int show_Share_Page()
{
cout << "\n共享页表:\n";
cout << "进程号\t" << "页号\t" << "共享状态\n";
int a = Share_Page.size();
for (int i = 0; i < a; i++)
cout << Share_Page[i].pro_id << "\t" << Share_Page[i].pages_num
<< "\t" << Share_Page[i].share_state << endl;
cout << endl;
return 0;
}
int main()
{
init();
PCB one;
PCB two;
int b = 0;
int c = 0;
while (1)
{
if (b == 0)
{
one.show();
two.show();
}
if (c == 0)
{
cout << "程序有如下功能:\n"
<< "1.输入1进程的逻辑地址\n"
<< "2.输入2进程的逻辑地址\n"
<< "3.显示共享页表\n"
<< "4.结束程序\n\n"
<< "请选择一个功能选项:";
}
int a;
cin >> a;
if (a == 1)
{
one.inquiry();
b = 0;
c = 0;
}
else if (a == 2)
{
two.inquiry();
b = 0;
c = 0;
}
else if (a == 3)
{
show_Share_Page();
b = 1;
c = 0;
}
else if (a == 4)
break;
else
{
cout << "输入错误,请重新输入!";
b = 1;
c = 1;
continue;
}
}
system("pause");
return 0;
}