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

📄 zvm.cpp

📁 自己开发的类汇编语言脚本语言虚拟机
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        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 + -