/* CPU模拟器 1.先用malloc动态分配一个32768长度的short类型的一维数组,模拟主存。 2.将主存初始化为0后,将指令序列从文件中读出,一条指令是32个01组成的字符串, 每8位转化为一个short整型,即代码段中每四位short是一条指令。 3.用程序计数器ip定位运行到哪条指令,第一位short是指令类型,第二位确定源寄 存器和目的寄存器,第三位和第四位转化为一个立即数,若第三位大于128说明 立即数是负数,要注意区分转化。 3.分析完指令后要将ip+4(主存4个short是一条指令),指向下一条指令。 4.取得并分析指令后根据指令类型在自动机里执行相应的case语句,即完成相应指令 操作。 5.完成后输出所有寄存器的值,并且判断是否是停机指令。若为停机指令,则自动机 输出相应停机状态,退出while循环,指令执行完毕。遇到停机指令后,输出代码段 和数据段的值,代码段把每四位short整型转化位int型输出,数据每两位转化并输出。 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define CMD_LEN 32 //每条指令长度
#define MEM_SIZE 32768 //模拟主存长度
#define CODE_GROUP 4 //指令占用4位
#define DATA_GROUP 2 //数据占用2位
#define EIGHTBYTE 256 //2进制数左移8位,扩大256倍
typedef struct reg
{
short genReg[9];//1~4存放数据,5~8存放地址
short ir[2]; //ir[0]:存放指令类型 ir[1]:存放源寄存器和目的寄存器
short ip; //程序计数器
short flag; //标志寄存器
short numReg; //立即数寄存器
}Register;
short *Init(Register* Reg); //主存初始化
void ReadCmdFile(short* memory); //将指令集放入主存
short byte_to_short(char* s,int start); //二进制数转化为十进制数
void Getcmd(short* memory,Register* Reg); //取指令
short state_trans(short* memory,Register* Reg);//根据指令类型选择操作
void PutReg(Register* Reg); //展示寄存器数据
void Outmemory(short* memory); //展示主存数据,代码段和数据段
void Data_transfer(short* memory,Register* Reg);//数据传递
void Arith_add(short* memory,Register* Reg); //加法
void Arith_sub(short* memory,Register* Reg); //减法
void Arith_multiply(short* memory,Register* Reg);//乘法
void Arith_div(short* memory,Register* Reg); //除法
void And_oper(short* memory,Register* Reg); //与操作
void or_oper(short* memory,Register* Reg); //或操作
void Not_oper(short* memory,Register* Reg); //非操作
void Compare(short* memory,Register* Reg); //比较操作
void Jump(short* memory,Register* Reg); //跳转操作
void Input(short* memory,Register* Reg); //输入操作
void Output(short* memory,Register* Reg); //输出操作
int main()
{
int stop = 0; //循环结束标志
Register Reg; //寄存器
short* memory = Init(&Reg); //初始化主存和寄存器
ReadCmdFile(memory); //将指令集载入主存
while(!stop)
{
Getcmd(memory,&Reg);
stop = State_trans(memory,&Reg);
}
Outmemory(memory);
free(memory);
return 0;
}
short* Init(Register* Reg)
{
int i = 0;
short* p = (short*)malloc(sizeof(short)*MEM_SIZE);
for( i = 0;i <= MEM_SIZE;i++)
{
p[i] = 0;
}
reg->flag = 0;
for( i = 0;i<9; i++)
{
Reg-> genReg[i] = 0;
}
Reg->ip = 0;
Reg->ir[0] = 0;
Reg->ir[1] = 0;
Reg->numReg = 0;
return p;
}
ReadCmdFile(short* memory)
{
FILE fp = fopen("dict.dic","r");
char s[CMD_LEN+1] = ""; //结束符号
int i = 0;
while(fscanf(fp,"%s",s))
{
if(feof(fp))
break;
memory[i++] = byte_to_short(s, 0);
memory[i++] = byte_to_short(s, 8);
memory[i++] = byte_to_short(s, 16);
memory[i++] = byte_to_short(s, 24);
}
}
short byte_to_short(char* s,int start)
{
int j = 7,i = 0;
int sum = 0;
for(i = start;i < start + 8 ; i++)
{
sum += (s[i]-'0')*pow^(2,j);
j--;
}
return sum;
}
void Getcmd(short* memory,Register* Reg) //取指令
{
Reg->ir[0] = memory[Reg->ip];
Reg->ir[1] = memory[Reg->ip+1];
if(memory[Reg->ip+2] >= 128) //立即数有可能是负数
Reg->numReg = (memory[Reg->ip+2]-EIGHTBYTE)* EIGHTBYTE + memory[Reg->ip+3];
else
Reg->numReg = memory[Reg->ip+2] * EIGHTBYTE + memory[Reg->ip+3];
Reg->ip += 4;
}
short State_trans(short* memory,Register* Reg) //选择功能
{
int type = Reg->[0];
int stopflag = 0;
switch(type)
{
case 0:
stopflag = 1;
break;
case 1:
Data_transfer(memory,Reg);
break;
case 2:
Arith_add(memory, Reg);
break;
case 3:
Arith_sub(memory, Reg);
break;
case 4:
Arith_multiply(memory, Reg);
break;
case 5:
Arith_div(memory, Reg);
break;
case 6:
And_oper(memory, Reg);
break;
case 7:
Or_oper(memory, Reg);
break;
case 8:
Not_oper(memory, Reg);
break;
case 9:
Compare(memory, Reg);
break;
case 10:
Jump(memory, Reg);
break;
case 11:
Input(memory, Reg);
break;
case 12:
Output(memory, Reg);
break;
}
PutReg(Reg);
if(stopflag)
return 1;
else
return 0;
}
void PutReg(Register* Reg)
{
printf("IP = %hd",Reg->ip);
printf("flag = %hd",Reg->flag);
printf("ir = %hd",Reg->ir[0]*EIGHTBYTE+Reg->ir[1]);
printf("ax1 = %hd ax2 = %hd ax3 = %hd ax4 = %hd",Reg->genReg[1]
,Reg->genReg[2],Reg->genReg[3],Reg->genReg[4]);
printf("ax5 = %hd ax6 = %hd ax7 = %hd ax8 = %hd",Reg->genReg[5]
,Reg->genReg[6],Reg->genReg[7],Reg->genReg[8]);
}
void Outmemory(short* memory)
{
int i,j,count = 0,sum;
printf("\ncodeSegment:\n");
for( i = 0 ; i < 16 ; i++ )
{
for(j=0;j<8;j++)
{
sum = memory[count]*pow(2,24)+memory[count+1]*pow(2,16)
+memory[count+2]*pow(2,8)+memory[count+3];
printf("%d",sum);
count+=4;
}
}
printf("\ncodeSegment:\n");
count = 16384;
for( i = 0 ; i < 16 ; i++ )
{
for(j=0;j<16;j++)
{
sum = memory[count]+memory[count+1]*EIGHTBYTE; //小端方式
printf("%d",sum);
count += 2;
}
}
printf("\n");
}
void Data_transfer(short* memory,Register* Reg)
{
short Sreg = Reg->ir[1] % 16 ;//低四位表示源寄存器
short Dreg = Reg->ir[1] / 16 ;//高四位表示目的寄存器
if(Sreg == 0 )//立即数->寄存器
{
Reg->genReg[Dreg] = Reg-> numReg;
}
else if (Sreg >= 5 && Dreg <= 4)//M->R
{
Reg->genReg[Dreg] = memory[Reg->genReg[Sreg]];
}
else if (Sreg <= 4 && Dreg >= 5)//R->M
{
memory[Reg->genReg[Dreg]] = Reg->genReg[Sreg];
}
else if (Sreg <= 4 && Dreg <= 4)//R->R
{
Reg->genReg[Dreg] = Reg->genReg[Sreg];
}
}
void Arith_sub(short* memory, Register* Reg)//减法
{
short Sreg = Reg->ir[1] % 16;
short Dreg = Reg->ir[1] / 16;
if (Sreg == 0 && Dreg <= 4)//立即数->R
{
Reg->genReg[Dreg] -= Reg->numReg;
}
else if (Sreg == 0 && Dreg >= 5)
{
memory[Reg->genReg[Dreg]] -= Reg->numReg;
}
else if (Sreg >= 5 && Dreg <= 4)//M->R
{
Reg->genReg[Dreg] -= memory[Reg->genReg[Sreg]];
}
else if (Sreg >= 5 && Dreg >= 5)//M->M
{
memory[Reg->genReg[Dreg]] -= memory[Reg->genReg[Sreg]];
}
else if (Sreg <= 4 && Dreg >= 5)//R->M
{
memory[Reg->genReg[Dreg]] -= Reg->genReg[Sreg];
}
else if (Sreg <= 4 && Dreg <= 4)//R->R
{
Reg->genReg[Dreg] -= Reg->genReg[Sreg];
}
}
void Arith_multiply(short* memory, Register* Reg)//乘法
{
short Sreg = Reg->ir[1] % 16;
short Dreg = Reg->ir[1] / 16;
if (Sreg == 0 && Dreg <= 4)//立即数->R
{
Reg->genReg[Dreg] *= Reg->numReg;
}
else if (Sreg == 0 && Dreg >= 5)
{
memory[Reg->genReg[Dreg]] *= Reg->numReg;
}
else if (Sreg >= 5 && Dreg <= 4)//M->R
{
Reg->genReg[Dreg] *= memory[Reg->genReg[Sreg]];
}
else if (Sreg >= 5 && Dreg >= 5)
{
memory[Reg->genReg[Dreg]] *= memory[Reg->genReg[Sreg]];
}
else if (Sreg <= 4 && Dreg >= 5)//R->M
{
memory[Reg->genReg[Dreg]] *= Reg->genReg[Sreg];
}
else if (Sreg <= 4 && Dreg <= 4)//R->R
{
Reg->genReg[Dreg] *= Reg->genReg[Sreg];
}
}
void Arith_div(short* memory, Register* Reg)//除法
{
short Sreg = Reg->ir[1] % 16;
short Dreg = Reg->ir[1] / 16;
if (Sreg == 0 && Dreg <= 4)//立即数->R
{
Reg->genReg[Dreg] /= Reg->numReg;
}
else if (Sreg == 0 && Dreg >= 5)
{
memory[Reg->genReg[Dreg]] /= Reg->numReg;
}
else if (Sreg >= 5 && Dreg <= 4)//M->R
{
Reg->genReg[Dreg] /= memory[Reg->genReg[Sreg]];
}
else if (Sreg >= 5 && Dreg >= 5)
{
memory[Reg->genReg[Dreg]] /= memory[Reg->genReg[Sreg]];
}
else if (Sreg <= 4 && Dreg >= 5)//R->M
{
memory[Reg->genReg[Dreg]] /= Reg->genReg[Sreg];
}
else if (Sreg <= 4 && Dreg <= 4)//R->R
{
Reg->genReg[Dreg] /= Reg->genReg[Sreg];
}
}
void And_oper(short* memory, Register* Reg)//与
{
short Sreg = Reg->ir[1] % 16;
short Dreg = Reg->ir[1] / 16;
if (Sreg == 0 && Dreg <= 4)//立即数 && R
{
if (Reg->genReg[Dreg] && Reg->numReg)
Reg->genReg[Dreg] = 1;
else Reg->genReg[Dreg] = 0;
}
else if (Sreg == 0 && Dreg >= 5)//立即数 && M
{
if (memory[Reg->genReg[Dreg] && Reg->numReg])
memory[Reg->genReg[Dreg]] = 1;
else memory[Reg->genReg[Dreg]] = 0;
}
else if (Sreg >= 5 && Dreg <= 4)//M && R
{
if (Reg->genReg[Dreg] && memory[Reg->genReg[Sreg]])
Reg->genReg[Dreg] = 1;
else Reg->genReg[Dreg] = 0;
}
else if (Sreg >= 5 && Dreg >= 5)//M && M
{
if (memory[Reg->genReg[Dreg]] && memory[Reg->genReg[Sreg]])
memory[Reg->genReg[Dreg]] = 1;
else memory[Reg->genReg[Dreg]] = 0;
}
else if (Sreg <= 4 && Dreg >= 5)
{
if (memory[Reg->genReg[Dreg]] && Reg->genReg[Sreg])
memory[Reg->genReg[Dreg]] = 1;
else memory[Reg->genReg[Dreg]] = 0;
}
else if (Sreg <= 4 && Dreg <= 4)//R && R
{
if (Reg->genReg[Dreg] && Reg->genReg[Sreg])
Reg->genReg[Dreg] = 1;
else Reg->genReg[Dreg] = 0;
}
}
void Or_oper(short* memory, Register* Reg)
{
short Sreg = Reg->ir[1] % 16;
short Dreg = Reg->ir[1] / 16;
if (Sreg == 0 && Dreg <= 4)//立即数 && R
{
if (Reg->genReg[Dreg] || Reg->numReg)
Reg->genReg[Dreg] = 1;
else Reg->genReg[Dreg] = 0;
}
else if (Sreg == 0 && Dreg >= 5)//立即数 && M
{
if (memory[Reg->genReg[Dreg] || Reg->numReg])
memory[Reg->genReg[Dreg]] = 1;
else memory[Reg->genReg[Dreg]] = 0;
}
else if (Sreg >= 5)//M && R
{
if (Reg->genReg[Dreg] || memory[Reg->genReg[Sreg]])
Reg->genReg[Dreg] = 1;
else Reg->genReg[Dreg] = 0;
}
}
void Not_oper(short* memory, Register* Reg)
{
short Sreg = Reg->ir[1] % 16;
short Dreg = Reg->ir[1] / 16;
if (Sreg == 0)//
{
if (!Reg->genReg[Dreg])
Reg->genReg[Dreg] = 1;
else Reg->genReg[Dreg] = 0;
}
else if (Sreg >= 5)
{
if (!memory[Reg->genReg[Sreg]])
memory[Reg->genReg[Sreg]] = 1;
else memory[Reg->genReg[Sreg]] = 0;
}
}
void Compare(short* memory, Register* Reg)
{
short Sreg = Reg->ir[1] % 16;
short Dreg = Reg->ir[1] / 16;
if (Sreg == 0 && Dreg <= 4)
{
if (Reg->genReg[Dreg] == Reg->numReg)
Reg->flag = 0;
else if (Reg->genReg[Dreg] > Reg->numReg)
Reg->flag = 1;
else if (Reg->genReg[Dreg] < Reg->numReg)
Reg->flag = -1;
}
else if (Sreg == 0 && Dreg >= 5)
{
if (memory[Reg->genReg[Dreg]] == Reg->numReg)
Reg->flag = 0;
else if (memory[Reg->genReg[Dreg]] > Reg->numReg)
Reg->flag = 1;
else Reg->flag = -1;
}
else if (Sreg >= 5)
{
if (Reg->genReg[Dreg] == memory[Reg->genReg[Sreg]])
Reg->flag = 0;
else if (Reg->genReg[Dreg] > memory[Reg->genReg[Sreg]])
Reg->flag = 1;
else if (Reg->genReg[Dreg] < memory[Reg->genReg[Sreg]])
Reg->flag = -1;
}
else if (Sreg <= 4)
{
if (Reg->genReg[Dreg] == Reg->genReg[Sreg])
Reg->flag = 0;
else if (Reg->genReg[Dreg] > Reg->genReg[Sreg])
Reg->flag = 1;
else Reg->flag = -1;
}
}
void Jump(short* memory, Register* Reg)
{
int state = Reg->ir[1];
if (state == 0)//无条件跳转
{
Reg->ip += Reg->numReg - 4;
}
else if (state == 1)
{
if (Reg->flag == 0)
Reg->ip += Reg->numReg - 4;
}
else if (state == 2)
{
if (Reg->flag == 1)
Reg->ip += Reg->numReg - 4;
}
else if (state == 3)
{
if (Reg->flag == -1)
Reg->ip += Reg->numReg - 4;
}
}
void Input(short* memory, Register* Reg)
{
short Dreg = Reg->ir[1] / 16;
printf("in:\n");
if (Dreg <= 4)
scanf("%hd", &Reg->genReg[Dreg]);
else scanf("%hd", &memory[Reg->genReg[Dreg]]);
}
void Output(short* memory, Register* Reg)
{
short Dreg = Reg->ir[1] / 16;
printf("out: ");
if (Dreg <= 4)
printf("%hd\n", Reg->genReg[Dreg]);
else printf("%hd\n", memory[Reg->genReg[Dreg]]);
}
今天的文章冯多依曼CPU——C语言实现分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/59736.html