计算机系统基础2:实验2 用C语言编写程序模拟TLB

计算机系统基础2:实验2 用C语言编写程序模拟TLB

提示:根据《计算机系统基础》 中给出的解释来解决更容易

题目要求:

  1. 能够描述利用快表进行虚拟存储的过程。
  2. 能够使用高级语言仿真快表。

#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上运行的结果

声明:这个我有借鉴学长的思路,在Windows上的dev c++运行是没有问题的,但是在macos 的 Xcode上运行会出现bug,可能是溢出的问题,呃呃呃呃,我也看不懂那些指令!

总结:

秘诀:一定要看书,一定要看书!!
那什么我C语言基础比较差,所以这个如果理解了原理再做起来是很快的,B站的搜的袁春风老师的课就很好理解!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值