⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.cpp

📁 一个简单的虚拟机和虚拟操作系统
💻 CPP
字号:
#include "stdafx.h"
#include "all.h"
#include "Instruction.h"
#include "VM.h"
#include "CPU.h"
#include "PCB.h"

extern VM vm;
extern CString msg;
CPU::CPU()
{
	Reset();
}

void CPU::Reset()
{
	PC = 0;
	IR[0] = -1;
}
/*
* fetch instruction to IR then update PC
*/
void CPU::FetchIns()
{
	Assert_InsADRS(PC);
	int address = GetDirAddress(PC);
	int opCode = mem[address];
	IR[0] = opCode;
	switch(opCode)
	{
	case LOAD:
	case STOR:
	case MOV:
	case ADD:
	case SUB:
	case MPY:
	case DIV:
	case JPZ:
		IR[1] = mem[address+1];
		IR[2] = mem[address+2];
		PC += 3;
		break;

	case INC:
	case DEC:
	case JMP:
	case OPEN:
	case CLOSE:
	case _IN:
	case _OUT:
		IR[1] = mem[address+1];
		PC += 2;
		break;

	case HALT:
		PC += 1;
		break;

	default:throw BAD_INS;
	}
}
void CPU::DoOperation()
{
	switch(IR[0])
	{
	case LOAD:Handle_LOAD(IR[1],IR[2]);break;
	case STOR:Handle_STOR(IR[1],IR[2]);break;
	case MOV:Handle_MOV(IR[1],IR[2]);break;
	case ADD:Handle_ADD(IR[1],IR[2]);break;
	case SUB:Handle_SUB(IR[1],IR[2]);break;
	case MPY:Handle_MPY(IR[1],IR[2]);break;
	case DIV:Handle_DIV(IR[1],IR[2]);break;
	case JPZ:Handle_JPZ(IR[1],IR[2]);break;

	case INC:Handle_INC(IR[1]);break;
	case DEC:Handle_DEC(IR[1]);break;
	case JMP:Handle_JMP(IR[1]);break;
	case OPEN:Handle_OPEN(IR[1]);break;
	case CLOSE:Handle_CLOSE(IR[1]);break;
	case _IN:Handle_IN(IR[1]);break;
	case _OUT:Handle_OUT(IR[1]);break;

	case HALT:Handle_HALT();break;

	case -1:return;
	default:throw BAD_INS;
	}
}
/***********************************************
 * assert the register ID or memory 
 * adderss is valid
 */
inline void CPU::Assert_REG(int r)
{
	if(r<0 || r>=REG_SIZE)
		throw BAD_REG;
}

inline void CPU::Assert_InsADRS(int address)
{
	if(address<0 || address>=PILR)
		throw BAD_ADDRESS;
}

inline void CPU::Assert_DataADRS(int address)
{
	if(address<PILR || address>=PILR+PDLR)
		throw BAD_ADDRESS;
}

inline int CPU::GetDirAddress(int address)
{
	int DirAddress = address+PAR;
	if(DirAddress >= MEM_SIZE)
		throw OUT_OF_MEM;
	return DirAddress;
}

/***********************************************
 * handle the operations
 */
inline void CPU::Handle_LOAD(int r,int m)
{
	Assert_REG(r);
	Assert_DataADRS(m);

	CString nmsg;
	nmsg.Format("将内存地址%d中的值加载到R%d\r\n",m,r);
	msg+=nmsg;

	R[r] = mem[this->GetDirAddress(m)];
}
inline void CPU::Handle_STOR(int m,int r)
{
	Assert_REG(r);
	Assert_DataADRS(m);

	CString nmsg;
	nmsg.Format("将R%d的值保存到内存地址%d处\r\n",r,m);
	msg+=nmsg;

	mem[this->GetDirAddress(m)] = R[r];
}
inline void CPU::Handle_MOV(int r1,int r2)
{
	Assert_REG(r1);
	Assert_REG(r2);

	CString nmsg;
	nmsg.Format("将R%d的值移到R%d\r\n",r2,r1);
	msg+=nmsg;

	R[r1] = R[r2];
}
inline void CPU::Handle_ADD(int r1,int r2)
{
	Assert_REG(r1);
	Assert_REG(r2);

	CString nmsg;
	nmsg.Format("以R%d的值加上R%d的值\r\n",r1,r2);
	msg+=nmsg;

	R[r1] += R[r2];
}
inline void CPU::Handle_SUB(int r1,int r2)
{
	Assert_REG(r1);
	Assert_REG(r2);

	CString nmsg;
	nmsg.Format("以R%d的值减去R%d的值\r\n",r1,r2);
	msg+=nmsg;

	R[r1] -= R[r2];
}
inline void CPU::Handle_MPY(int r1,int r2)
{
	Assert_REG(r1);
	Assert_REG(r2);

	CString nmsg;
	nmsg.Format("以R%d的值乘以R%d的值\r\n",r1,r2);
	msg+=nmsg;

	R[r1] *= R[r2];
}
inline void CPU::Handle_DIV(int r1,int r2)
{
	Assert_REG(r1);
	Assert_REG(r2);

	CString nmsg;
	nmsg.Format("以R%d的值除以R%d的值\r\n",r1,r2);
	msg+=nmsg;

	if(R[r2] == 0)
		throw DIVIDED_BY_ZERO;
	R[r1] /= R[r2];
}
inline void CPU::Handle_INC(int r)
{
	Assert_REG(r);

	CString nmsg;
	nmsg.Format("R%d加加\r\n",r);
	msg+=nmsg;

	R[r]++;
}
inline void CPU::Handle_DEC(int r)
{
	Assert_REG(r);

	CString nmsg;
	nmsg.Format("R%d减减\r\n",r);
	msg+=nmsg;

	R[r]--;
}
inline void CPU::Handle_JMP(int m)
{
	Assert_InsADRS(m);

	CString nmsg;
	nmsg.Format("跳到内存地址%d处\r\n",m);
	msg+=nmsg;

	PC = m;
}
inline void CPU::Handle_JPZ(int m,int r)
{
	Assert_REG(r);
	Assert_InsADRS(m);

	if(R[r] == 0)
	{
		PC = m;
		CString nmsg;
		nmsg.Format("R%d是0,跳到内存地址%d处\r\n",r,m);
		msg+=nmsg;
	}
	else
	{
		CString nmsg;
		nmsg.Format("R%d不是0,不执行跳转\r\n",r);
		msg+=nmsg;
	}
}
inline void CPU::Handle_OPEN(int IO)
{
	if(IO == IRQA)
		vm.PauseProcess();
}
inline void CPU::Handle_CLOSE(int IO)
{
}
inline void CPU::Handle_IN(int r)
{
}
inline void CPU::Handle_OUT(int r)
{
}
inline void CPU::Handle_HALT()
{
	msg+="终止\r\n";
	vm.StopProcess();
	Reset();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -