📄 zvm.cpp
字号:
printf ( "指令总数: %d\n", g_Script.InstrStream.iSize );
// ---- 成功返回
return LOAD_OK;
}
/**********************************************************************************************
*
* RunScript ()
*
* 运行脚本
*/
void RunScript ()
{
// 结束循环标志
bool bExitLoop = false;
// 循环操作,直到按下一个键为止
while ( !_kbhit() )
{
// 处理脚本暂停标志
if ( g_Script.iIsPaused )
{
if ( GetCurrTime() >= g_Script.iPauseEndTime )
{
g_Script.iIsPaused = false;
}
else
{
continue;
}
}
// 保存当前指令指针,用以确定指令执行之后是否需要增加指令指针计数
// 确定方式是: 在指令执行结束后用那时的指令指针与这一步保存的指针进行比较,
// 若不同,说明指令运行后改变了指令指针,所以不需改变指令指针的值
// 若相同,则需要增加指令指针的值
int iCurrInstr = g_Script.InstrStream.iCurrInstr;
// 取得当前操作码
int iOpCode = g_Script.InstrStream.pInstrs [ iCurrInstr ].iOpCode;
// 打印指令的一些信息
printf ( "\t" );
if ( iOpCode < 10 )
{
printf ( " %d", iOpCode );
}
else
{
printf ( "%d", iOpCode );
}
printf ( " %s", ppstrMnemonics [ iOpCode ] );
// 根据操作码执行指令
switch ( iOpCode )
{
// ---- 双操作数指令
// Move
case INSTR_MOV:
// 算数指令
case INSTR_ADD:
case INSTR_SUB:
case INSTR_MUL:
case INSTR_DIV:
case INSTR_MOD:
case INSTR_EXP:
// 位操作指令
case INSTR_AND:
case INSTR_OR:
case INSTR_XOR:
case INSTR_SHL:
case INSTR_SHR:
{
// 局部复制目的操作数和源操作数
Value Dest = ResolveOpValue ( 0 );
Value Source = ResolveOpValue ( 1 );
// 执行指令
switch ( iOpCode )
{
// Move
case INSTR_MOV:
// 如果目的操作数和源操作数地址相同,跳过
if ( ResolveOpPntr ( 0 ) == ResolveOpPntr ( 1 ) )
{
break;
}
// 拷贝源操作数到局部复制的目的操作数中
CopyValue ( &Dest, Source );
break;
// Add
case INSTR_ADD:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral += ResolveOpAsInt ( 1 );
}
else
{
Dest.fFloatLiteral += ResolveOpAsFloat ( 1 );
}
break;
// Sub
case INSTR_SUB:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral -= ResolveOpAsInt ( 1 );
}
else
{
Dest.fFloatLiteral -= ResolveOpAsFloat ( 1 );
}
break;
// Mul
case INSTR_MUL:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral *= ResolveOpAsInt ( 1 );
}
else
{
Dest.fFloatLiteral *= ResolveOpAsFloat ( 1 );
}
break;
// Div
case INSTR_DIV:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral /= ResolveOpAsInt ( 1 );
}
else
{
Dest.fFloatLiteral /= ResolveOpAsFloat ( 1 );
}
break;
// Mod
case INSTR_MOD:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral %= ResolveOpAsInt ( 1 );
}
break;
// Exp
case INSTR_EXP:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral = (int) pow ( (float)Dest.iIntLiteral, ResolveOpAsInt ( 1 ) );
}
else
{
Dest.fFloatLiteral = (float) pow ( Dest.fFloatLiteral, ResolveOpAsFloat ( 1 ) );
}
break;
// And
case INSTR_AND:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral &= ResolveOpAsInt ( 1 );
}
break;
// Or
case INSTR_OR:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral |= ResolveOpAsInt ( 1 );
}
break;
// Xor
case INSTR_XOR:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral ^= ResolveOpAsInt ( 1 );
}
break;
// shl
case INSTR_SHL:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral <<= ResolveOpAsInt ( 1 );
}
break;
// shr
case INSTR_SHR:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral >>= ResolveOpAsInt ( 1 );
}
break;
}
// 将局部赋值的目的操作数写入到真正的目的操作数地址处
*ResolveOpPntr ( 0 ) = Dest;
// 打印操作过程
PrintOpIndir ( 0 );
printf ( ", " );
PrintOpValue ( 1 );
break;
}
// ---- 单操作数指令
case INSTR_NEG:
case INSTR_NOT:
case INSTR_INC:
case INSTR_DEC:
{
// 取得目的操作数类型
int iDestStoreType = GetOpType ( 0 );
// 局部赋值目的操作数
Value Dest = ResolveOpValue ( 0 );
// 处理指令
switch ( iOpCode )
{
// Neg
case INSTR_NEG:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iInstrIndex = -Dest.iIntLiteral;
}
else
{
Dest.fFloatLiteral = -Dest.fFloatLiteral;
}
break;
// Not
case INSTR_NOT:
if ( Dest.iType == OP_TYPE_INT )
{
Dest.iIntLiteral = ~Dest.iIntLiteral;
}
break;
// Inc
case INSTR_INC:
if ( Dest.iType == OP_TYPE_INT )
{
++ Dest.iIntLiteral;
}
else
{
++ Dest.fFloatLiteral;
}
break;
// Dec
case INSTR_DEC:
if ( Dest.iType == OP_TYPE_INT )
{
-- Dest.iIntLiteral;
}
else
{
-- Dest.fFloatLiteral;
}
break;
}
// 将结果写会目的操作数
*ResolveOpPntr ( 0 ) = Dest;
// 打印操作信息
PrintOpIndir ( 0 );
break;
}
// ---- 字符串处理
case INSTR_CONCAT:
{
// 局部赋值目的操作数
Value Dest = ResolveOpValue ( 0 );
// 局部复制源操作数字符串
char *pstrSourceString = ResolveOpAsString ( 1 );
// 检测目的操作数类型是否是字符串
if ( Dest.iType != OP_TYPE_STRING )
{
break;
}
// 计算连接后的字符串长度
size_t iNewStringLength = strlen ( Dest.pstrStringLiteral ) + strlen ( pstrSourceString );
// 为新字符串分配空间
char *pstrNewString = new char [ iNewStringLength + 1 ];
// 赋值原目的串到新串
strcpy_s ( pstrNewString, iNewStringLength+1, Dest.pstrStringLiteral );
// 连接字符串
strcat_s ( pstrNewString, iNewStringLength+1, pstrSourceString );
// 释放原目的串
delete Dest.pstrStringLiteral;
// 将新串赋值给目的串
Dest.pstrStringLiteral = pstrNewString;
// 将局部赋值的目的操作数写会真正的目的操作数地址处
*ResolveOpPntr ( 0 ) = Dest;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -