冯多依曼CPU——C语言实现

冯多依曼CPU——C语言实现hahah_cpu的c模拟器

/* 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

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注