📄 virtualmachine.cpp
字号:
void CVirtualMachine::STOP()
{
m_ST = MS_STOP;
}
// Error instruction
void CVirtualMachine::ERR()
{
m_IE = AD(m_NI+VM_ICSIZE);
m_ST = MS_ERROR;
m_NI += VM_ICSIZE;
}
// The input instruction
void CVirtualMachine::INP()
{
BYTE what = m_pbMem[m_NI+VM_ICSIZE];
m_SP += SE_SIZE;
SE(m_SP).m_nType = what;
switch (what)
{
case SE_CHAR: // Read a character
CHAR c;
c=getchar();
CV_CHAR(SE(m_SP).m_Info) = c;
break;
case SE_INTEGER:
INTEGER n;
scanf("%d",&n);
c=getchar(); // read enter from the buffer
CV_INTEGER(SE(m_SP).m_Info) = n;
break;
case SE_REAL:
REAL x;
scanf("%f",&x);
c=getchar(); // read enter from the buffer
CV_REAL(SE(m_SP).m_Info) = x;
break;
default:
m_ST = MS_ERROR;
}
m_NI += VM_ICSIZE + 1; // BYTE size = 1
}
// The output instruction
void CVirtualMachine::OUTP()
{
switch (SE(m_SP).m_nType)
{
case SE_CHAR: // Print a character
printf("%c",CV_CHAR(SE(m_SP).m_Info));
break;
case SE_INTEGER:
printf("%d",CV_INTEGER(SE(m_SP).m_Info));
break;
case SE_REAL:
printf("%f",CV_REAL(SE(m_SP).m_Info));
break;
default:
m_ST = MS_ERROR;
}
m_SP -= SE_SIZE;
m_NI += VM_ICSIZE ;
}
// The AND logical instruction
void CVirtualMachine::AND()
{
m_SP -= SE_SIZE;
if (SE(m_SP).m_nType != SE(m_SP + SE_SIZE).m_nType)
m_ST = MS_ERROR;
else
SE(m_SP).m_Info = SE(m_SP).m_Info && SE(m_SP + SE_SIZE).m_Info;
m_NI += VM_ICSIZE;
}
// The OR logical instruction
void CVirtualMachine::OR()
{
m_SP -= SE_SIZE;
if (SE(m_SP).m_nType != SE(m_SP + SE_SIZE).m_nType)
m_ST = MS_ERROR;
else
SE(m_SP).m_Info = SE(m_SP).m_Info || SE(m_SP + SE_SIZE).m_Info;
m_NI += VM_ICSIZE;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/25/99 1:43:13 PM
// Function name : CVirtualMachine::LoadMemoryContent
// Description : This function Loads the memory content for the VM
// Return type : void
// Argument : REGISTER addrTo - The address of the VM Where the data is loaded
// Argument : BYTE *from - pointer to the buffer where the data is
// Argument : int count - length of the data
///////////////////////////////////////////////////////////////
void CVirtualMachine::LoadMemoryContent(REGISTER addrTo, BYTE *from, int count)
{
int addrEnd = (addrTo + count < m_nMemSize) ? addrTo + count : m_nMemSize;
for (int i = addrTo; i<addrEnd ; i++) // copy the memory content, can be optimized using memcpy
m_pbMem[i] = from[i-addrTo];
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/25/99 2:01:15 PM
// Function name : CVirtualMachine::NOP
// Description : The No Operation Instruction
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::NOP()
{
m_NI += VM_ICSIZE;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/27/99 11:00:08 AM
// Function name : CVirtualMachine::ENTER
// Description : Enter instruction This is support for advanced
// : programming languages, Like Pasca
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::ENTER()
{
// Parameter the entry level for procedure/function
BYTE level = m_pbMem[m_NI+VM_ICSIZE];
// Parameter the number of local variables alocated
REGISTER locals = AD(m_NI+VM_ICSIZE+1);
// Save the CALee's StackFrame pointer to the stack
m_SP += SE_SIZE;
SE(m_SP).m_nType = SE_ADDRESS;
CV_ADDRESS(SE(m_SP).m_Info) = m_FP;
REGISTER tmp = m_SP;
// Save the superior level Stack pointers to the stack
for (int i=0; i<level-1; i+=SE_SIZE)
{
m_SP+=SE_SIZE;
SE(m_SP) = SE(m_FP + (i+1) * SE_SIZE);
}
// Put own Stack Frame
m_SP += SE_SIZE;
SE(m_SP).m_nType = SE_ADDRESS;
CV_ADDRESS(SE(m_SP).m_Info) = tmp;
m_FP = tmp; // Set the new Frame Pointer
m_CFP = m_FP;
// Alloc local variables
m_SP += locals * SE_SIZE;
// increase the program counter
m_NI += VM_ICSIZE+VM_BYTES + 1;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/27/99 11:10:33 AM
// Function name : CVirtualMachine::LEAVE
// Description : Leave function / procedure , clears the display from the stack
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::LEAVE()
{
// Leaves the bullshit function or procedure
// free the stack
m_SP = m_FP - SE_SIZE;
m_FP = CV_ADDRESS(SE(m_FP).m_Info);
m_CFP = m_FP;
// increase the program counter
m_NI += VM_ICSIZE;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/27/99 1:37:32 PM
// Function name : CVirtualMachine::CHGSFR
// Description : This function is just changing the current frame pointer
// : To the level specified relatively, takes the FP from the current FP
// Return type : void
// Argument : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::CHGSFP(void)
{
// Parameter the entry level for procedure/function
BYTE level = m_pbMem[m_NI+VM_ICSIZE];
//now taking setting the FP
m_FP = CV_ADDRESS(SE(m_FP + level * SE_SIZE).m_Info);
// increase the program counter
m_NI += VM_ICSIZE+ 1;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/27/99 1:37:35 PM
// Function name : CVirtualMachine::RSTSFR
// Description : Restores the FP to the current FP
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::RSTSFP()
{
// restores FP
m_FP = m_CFP;
// increase the program counter
m_NI += VM_ICSIZE;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/28/99 12:58:01 PM
// Function name : CVirtualMachine::LODA
// Description : Load address to the stack offset relative
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::LODA()
{
m_SP += SE_SIZE;
StackEntry entry;
entry.m_nType = SE_ADDRESS;
CV_ADDRESS(entry.m_Info) = m_FP + SE_SIZE * OFFS(m_NI+VM_ICSIZE);
SE(m_SP) = entry;
m_NI += VM_ICSIZE + VM_BYTES;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/28/99 1:01:26 PM
// Function name : CVirtualMachine::LODAX
// Description : THe same as loda but relative to RX register
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::LODAX()
{
m_SP += SE_SIZE;
StackEntry entry;
entry.m_nType = SE_ADDRESS;
CV_ADDRESS(entry.m_Info) = m_FP + SE_SIZE * (m_RX+ OFFS(m_NI+VM_ICSIZE));
SE(m_SP) = entry;
m_NI += VM_ICSIZE + VM_BYTES;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 5/28/99 1:46:36 PM
// Function name : CVirtualMachine::LODEA
// Description : Loads the element pointed by the value pointed by the FP + offset
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::LODEA()
{
m_SP += SE_SIZE;
SE(m_SP) = SE( CV_ADDRESS(SE(m_FP + SE_SIZE * OFFS(m_NI+VM_ICSIZE)).m_Info));
m_NI += VM_ICSIZE + VM_BYTES;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/1/99 2:20:58 PM
// Function name : CVirtualMachine::PUSH
// Description : Pushes the specified register into the stack
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::PUSH()
{
BYTE reg = m_pbMem[m_NI+VM_ICSIZE];
m_SP += SE_SIZE;
SE(m_SP) = m_SREG[reg];
m_NI += VM_ICSIZE+1;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/1/99 2:21:28 PM
// Function name : CVirtualMachine::POP
// Description : Pops the TOS into the specified register
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::POP()
{
BYTE reg = m_pbMem[m_NI+VM_ICSIZE];
m_SREG[reg] = SE(m_SP);
m_SP -= SE_SIZE;
m_NI += VM_ICSIZE+1;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/2/99 11:14:39 AM
// Function name : CVirtualMachine::USTO
// Description : Put's the value pointed by the address in the Top of stack
// : in the top of stack
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::USTO()
{
SE(m_SP) = SE(CV_ADDRESS(SE(m_SP).m_Info));
m_NI += VM_ICSIZE;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/3/99 5:13:10 PM
// Function name : CVirtualMachine::Continue
// Description : This function continues the execution of the machine
// Return type : void
///////////////////////////////////////////////////////////////
REGISTER CVirtualMachine::Continue()
{
return Start (m_NI,m_SP);
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/4/99 3:45:25 PM
// Function name : CVirtualMachine::GetMem
// Description : Returns a pointer to the Virtual machine's memory
// Return type : BYTE *
///////////////////////////////////////////////////////////////
BYTE * CVirtualMachine::GetMem()
{
return m_pbMem;
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/4/99 9:50:11 AM
// Function name : CVirtualMachine::LoadMemoryContent
// Description : Load Memory content from a file
// Return type : int
// Argument : REGISTER addrTo
// Argument : CFile *from
// Argument : int count
///////////////////////////////////////////////////////////////
int CVirtualMachine::LoadMemoryContent(REGISTER addrTo, CFile *from, int count)
{
return from->Read( &m_pbMem[addrTo], count);
}
///////////////////////////////////////////////////////////////
// Programmer : Zoly Farkas
// Creation Date : 6/8/99 1:33:55 PM
// Function name : CVirtualMachine::NFJP
// Description : this is the oposite instruction to FJP, it jumps when Flag is FALSE
// Return type : void
///////////////////////////////////////////////////////////////
void CVirtualMachine::NFJP()
{
if (!CV_BOOLEAN(SE(m_SP).m_Info))
m_NI = AD(m_NI+VM_ICSIZE);
else
m_NI += VM_ICSIZE + VM_BYTES;
m_SP -= SE_SIZE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -