计算机系统基础2:实验2 用C语言编写程序模拟TLB
提示:根据《计算机系统基础》 中给出的解释来解决更容易
题目要求:
- 能够描述利用快表进行虚拟存储的过程。
- 能够使用高级语言仿真快表。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
struct TLB{
char Valid ;
char TlbTag[11];
char PPN[5];
int count;
}tlb[16]={
{'0',"0000000000","0000",0},
{'1',"0000000000","1000",1},
{'1',"0000000010","0001",2},
{'1',"0000000011","0000",3},
{'1',"0000000100","0011",4},
{'1',"0000000101","0100",5},
{'1',"0000000110","0101",6},
{'1',"0000000111","0110",14},
{'1',"0000001000","0000",15},
{'1',"0000001001","0000",7},
{'1',"0000001010","0000",8},
{'1',"0000001011","1000",9},
{'1',"0000001100","1000",10},
{'1',"0000001101","1000",11},
{'1',"0000001110","1000",12},
{'1',"0000001111","1000",13}
};
struct cache{
char Valid ;
char CacheTag[7];
char CacheData[34];
int count;
}cae[4][4]={
{
{'1',"000000","00000000000000000000000000000001",1},
{'1',"000001","00000000000000000000000000000010",2},
{'1',"000010","00000000000000000000000000000011",0},
{'1',"000011","00000000000000000000000000000100",3}
},{
{'0',"000000","00000000000000000000000000000101",3},
{'1',"000001","00000000000000000000000000000110",0},
{'1',"000010","00000000000000000000000000000111",1},
{'1',"000011","00000000000000000000000000001000",2}
},{
{'0',"000000","00000000000000000000000000001001",3},
{'1',"000001","00000000000000000000000000001010",1},
{'1',"000010","00000000000000000000000000001011",2},
{'1',"000011","00000000000000000000000000001100",0}
},{
{'0',"000000","00000000000000000000000000001101",3},
{'1',"000001","00000000000000000000000000001110",2},
{'1',"000010","00000000000000000000000000001111",1},
{'1',"000011","00000000000000000000000000000000",0}
}
};
char * PageTable(char binary[]){
static char sc[17];
srand((unsigned)time(NULL));
if(rand() % 101 <50) {
strcpy(sc,"2000000000000000");
}else{
strcpy(sc,"1001100111110000");
}
printf("返回值是:%s\n",sc);
return sc;
}
int Count(void){
int i,c=-1,max,min;
max = tlb[0].count ;
min = tlb[0].count;
for(i = 0;i<16;i++){
if(tlb[i].count>max){
max = tlb[i].count;
}if(tlb[i].count<min){
min = tlb[i].count;
c = i;
}
}
tlb[c].count = max+1;
return c;
}
char PPN(int h,char binary[]){
int i,sum = 0,z = 0;
char s[5];
for(i = 9;i>5;i--){
sum = sum+((binary[i]-'0')*pow(2,9-i));
}
int ppn = sum+1;
for(i = 3;i>=0;i--){
if(ppn-z>=pow(2,i)){
s[3-i] = ((ppn-z)/pow(2,i))+'0';
z = z+pow(2,i);
}else{
s[3-i] = 0+'0';
}
}
strcpy(tlb[h].PPN,s);
return 0;
}
char* Cache(char binary[]){
int w,i,c = -1;//w是组数
w = (binary[6]-'0')*2+(binary[7]-'0');
//printf("w=%d\n",w);
char binary1[7] ;
strncpy(binary1, binary, 6);
binary1[6]='\0';//strncpy函数存在一个问题 需要手动添加休止符'\0'
//printf("binary1:%s\n",binary1);
for(i = 0;i<4;i++){
//printf("CacheTag:%s\n",cae[w][i].CacheTag);
if(strcmp(binary1, cae[w][i].CacheTag) == 0 && cae[w][i].Valid =='1'){
c = 1;
printf("Cache命中\n");
printf("返回值是:%s\n",cae[w][i].CacheData);
}
}
if(c != 1){
printf("Cache不命中\n");
printf("返回值是:10001000100010001111111111111111\n");
}
return 0;
}
char * Tlb(char binary[]){
int i,t = 17,c = 0,o,j;
static char sc[11] ={0};
char binary1[11] = {0};
strncpy(binary1, binary, 10);
for(i = 0;i<16;i++){
if(strcmp(binary1, tlb[i].TlbTag) == 0 && tlb[i].Valid =='1'){
c = 1;
printf("TLB命中且");
for(j = 0;j<8;j++){
if(j<4){
sc[j] = tlb[i].PPN[j];
}else{
sc[j] = binary[j+6];
}
}//进行地址转换,根据PPN+后六位
Cache(sc);//访问Cache(此处即调用实验1的函数,因此需要将实验1的源文件导入);
// printf("sc:%s\n",sc);
}
if((tlb[i].Valid - '0') == 0){
t = i;
}
}
if(t == 17&& c != 1){
printf("TLB不命中且没有空闲行\n");
o = Count();
// printf("o:%d",o);
strcpy(tlb[o].TlbTag,binary1);
// printf("tlb[o].TlbTag:%s",tlb[o].TlbTag);
PPN(o,binary);
PageTable(binary);
}if(t != 17&&c != 1){
printf("TLB不命中且有空闲行\n");
tlb[t].Valid = 1+'0';
tlb[t].count = tlb[Count()].count;
// printf("count:%d",tlb[t].count);
strcpy(tlb[t].TlbTag,binary1);
PPN(t,binary);
PageTable(binary);//访问页表
}
return sc;
}
int main(int argc, char *argv[]) {
char binary[16];
int i;
for(i = 0;i < 4;i++){
printf("Test%d:",i+1);
scanf("%s",binary);
char *sc;
sc = Tlb(binary);
}
printf("\nTLB数据:\n");
printf("valid TLBTag PPN count\n");
for(i = 0;i<16;i++){
printf("%c %s %s %d",tlb[i].Valid,tlb[i].TlbTag,tlb[i].PPN,tlb[i].count);
printf("\n");
}
return 0;
}
测试举例:
声明:这个我有借鉴学长的思路,在Windows上的dev c++运行是没有问题的,但是在macos 的 Xcode上运行会出现bug,可能是溢出的问题,呃呃呃呃,我也看不懂那些指令!
总结:
秘诀:一定要看书,一定要看书!!
那什么我C语言基础比较差,所以这个如果理解了原理再做起来是很快的,B站的搜的袁春风老师的课就很好理解!