📄 cpu.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 + -