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

📄 zvm.cpp

📁 自己开发的类汇编语言脚本语言虚拟机
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
    文件:
        ZVM.cpp

    内容:
        执行 .ZSE 可执行文件的虚拟机的实现

    作者:
        张锦

    日期:
        01.05.2009

    版本:
        v 1.0
*/

// ---- 包含文件 ----------------------------------------------------------------------------------
    
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <conio.h>    
    #include <windows.h>
    
    using namespace std;

// ---- 全局常量 ----------------------------------------------------------------------------------

    
    // ---- 文件 ----------------------------------------------------------------------------------

        #define EXEC_FILE_EXT               ".ZSE"      // 可执行文件扩展名
        #define ZSE_ID_STRING               "ZSE0"      // .ZSE 文件标识

    // ---- LoadScript() 错误码 -------------------------------------------------------------------

        #define LOAD_OK                     0           // 加载成功
        #define LOAD_ERROR_FILE_IO          1           // 打开文件失败
        #define LOAD_ERROR_INVALID_ZSE      2           // 文件类型不正确
        #define LOAD_ERROR_UNSUPPORTED_VERS 4           // 版本不正确

    // ---- 操作数类型 ----------------------------------------------------------------------------

        #define OP_TYPE_NULL                -1          // 未初始化的操作数 / NULL
        #define OP_TYPE_INT                 0           // int型 字面量
        #define OP_TYPE_FLOAT               1           // float型 字面量
        #define OP_TYPE_STRING              2           // 字符串
        #define OP_TYPE_ABS_STACK_INDEX     3           // 绝对堆栈索引
        #define OP_TYPE_REL_STACK_INDEX     4           // 相对堆栈索引
        #define OP_TYPE_INSTR_INDEX         5           // 指令索引
        #define OP_TYPE_FUNC_INDEX          6           // 函数索引
        #define OP_TYPE_HOST_API_CALL_INDEX 7           // 主程序 API 调用索引
        #define OP_TYPE_REG                 8           // 寄存器

    // ---- 指令操作码 --------------------------------------------------------------------------------

        #define INSTR_MOV                   0

        #define INSTR_ADD                   1
        #define INSTR_SUB                   2
        #define INSTR_MUL                   3
        #define INSTR_DIV                   4
        #define INSTR_MOD                   5   
        #define INSTR_EXP                   6
        #define INSTR_NEG                   7
        #define INSTR_INC                   8
        #define INSTR_DEC                   9

        #define INSTR_AND                   10
        #define INSTR_OR                    11
        #define INSTR_XOR                   12
        #define INSTR_NOT                   13
        #define INSTR_SHL                   14
        #define INSTR_SHR                   15

        #define INSTR_CONCAT                16
        #define INSTR_GETCHAR               17
        #define INSTR_SETCHAR               18

        #define INSTR_JMP                   19
        #define INSTR_JE                    20
        #define INSTR_JNE                   21
        #define INSTR_JG                    22
        #define INSTR_JL                    23
        #define INSTR_JGE                   24
        #define INSTR_JLE                   25
        
        #define INSTR_PUSH                  26
        #define INSTR_POP                   27

        #define INSTR_CALL                  28
        #define INSTR_RET                   29
        #define INSTR_CALLHOST              30

        #define INSTR_PAUSE                 31
        #define INSTR_EXIT                  32

    // ---- 堆栈 ----------------------------------------------------------------------------------

        #define DEF_STACK_SIZE              1024        // 堆栈默认大小

    // ---- 强制转换 ------------------------------------------------------------------------------

        #define MAX_COERCION_STRING_SIZE    65         // 允许强制转换成字符串的最大字符串长度 

// ---- 数据结构 ----------------------------------------------------------------------------------

    // ---- 运行时值 ------------------------------------------------------------------------------

        struct Value
        {
            int     iType;      // 类型
            union
            {
                int     iIntLiteral;    // 整形字面量
                float   fFloatLiteral;  // 浮点型字面量
                char    *pstrStringLiteral;  // 字符串表索引
                int     iStackIndex;    // 堆栈索引
                int     iInstrIndex;    // 指令索引
                int     iFuncIndex;     // 函数索引
                int     iHostAPICallIndex;  // 主应用程序API调用索引
                int     iReg;           // 寄存器码
            };
            int     iOffsetIndex;       // 偏移量索引
        };

    // ---- 运行时堆栈 ----------------------------------------------------------------------------

        struct RuntimeStack
        {
            Value   *pElements;     // 堆栈元素
            int     iSize;          // 堆栈元素个数
            int     iTopIndex;      // 栈顶索引
            int     iFrameIndex;    // 当前堆栈框架顶部索引
        };

    // ---- 指令 ----------------------------------------------------------------------------------

        struct Instr                // 指令
        {
            int     iOpCode;        // 指令操作码
            int     iOpCount;       // 操作数个数
            Value   *pOpList;       // 操作数列表
        };

        struct InstrStream
        {
            Instr   *pInstrs;       // 指令本身
            int     iSize;          // 指令流中指令条数
            int     iCurrInstr;     // 当前指令
        };

    // ---- 函数 ----------------------------------------------------------------------------------

        struct Func
        {
            int     iEntryPoint;    // 函数入口点
            int     iParamCount;    // 参数个数
            int     iLocalDataSize; // 局部数据大小
            int     iStackFrameSize;// 堆栈框架的总的小
        };

    // ---- 主程序API调用 -------------------------------------------------------------------------

        struct HostAPICallTable
        {
            char    **ppstrCalls;   // 指向函数名数组的指针
            int     iSize;          // 数组中函数名的个数
        };

    // ---- 脚本 ----------------------------------------------------------------------------------

        struct Script
        {
            // 头数据

            int     iGlobalDataSize;    // 脚本全局数据大小

            // 数据

            int     iIsMainFuncPresent; // _Main() 是否存在
            int     iMainFuncIndex;     // _Main() 的索引
            int     iIsPaused;          // 是否被暂停
            int     iPauseEndTime;      // 如果暂停,什么时候继续

            // 寄存器

            Value   _RetVal;            // _RetVal 寄存器

            // 脚本数据

            InstrStream         InstrStream;      // 指令流
            RuntimeStack        Stack;            // 运行时堆栈
            Func*               pFuncTable;       // 函数表
            HostAPICallTable    HostAPICallTable; // 主程序API调用表
        };

// ---- 全局变量 ----------------------------------------------------------------------------------

    // ---- 脚本 ----------------------------------------------------------------------------------

        Script      g_Script;       // 全局脚本实例

    // ---- 指令助记符 ----------------------------------------------------------------------------

        char        ppstrMnemonics [][12]   = 
        {
            "Mov",
            "Add", "Sub", "Mul", "Div", "Mod", "Exp", "Neg", "Inc", "Dec",
            "And", "Or", "Xor", "Not", "SHL", "SHR", 
            "Concat", "GetChar", "SetChar", 
            "Jmp", "JE", "JNE", "JG", "JL", "JGE", "JLE",
            "Push", "Pop", 
            "Call", "Ret", "CallHost",
            "Pause", "Exit"
        };

    // ---- 读取字节数 ----------------------------------------------------------------------------

        size_t      g_iReadSize     = 0;

// ---- 函数原型 ----------------------------------------------------------------------------------
    
    // ---- 主函数 --------------------------------------------------------------------------------

        void    Init ();
        void    ShutDown ();

    // ---- 脚本接口 ------------------------------------------------------------------------------

        int     LoadScript ( char *pstrFileName );
        void    RunScript ();
        void    ResetScript ();

    // ---- 操作数接口 ----------------------------------------------------------------------------

        int     CoerceValueToInt ( Value &val );
        float   CoerceValueToFloat ( Value &val );
        char*   CoerceValueToString ( Value &val );

        void    CopyValue ( Value* pDest, Value &Source );

        int     GetOpType ( int iOpIndex );
        int     ResolveStackIndex ( int iIndex );
        int     ResolveOpStackIndex ( int iOpIndex );
        Value   ResolveOpValue ( int iOpIndex );
        int     ResolveOpType ( int iOpIndex );
        int     ResolveOpAsInt ( int iOpIndex );
        float   ResolveOpAsFloat ( int iOpIndex );
        char*   ResolveOpAsString ( int iOpIndex );
        int     ResolveOpAsInstrIndex ( int iOpIndex );
        int     ResolveOpAsFuncIndex ( int iOpIndex );
        char*   ResolveOpAsHostAPICall ( int iOpIndex );
        Value*  ResolveOpPntr ( int iOpIndex );

    // ---- 运行时堆栈接口 ------------------------------------------------------------------------

        Value   GetStackValue ( int iIndex );
        void    SetStackValue ( int iIndex, Value val );
        void    Push ( Value val );
        Value   Pop ();
        void    PushFrame ( int iSize );
        void    PopFrame ( int iSize );

    // ---- 函数表接口 ----------------------------------------------------------------------------

        Func    GetFunc ( int iIndex ); 

    // ---- 主程序 API 调用接口 -------------------------------------------------------------------

        char*   GetHostAPICall ( int iIndex ); 

    // ---- 打印帮助信息 --------------------------------------------------------------------------

        void    PrintOpIndir ( int iOpIndex );
        void    PrintOpValue ( int iOpIndex );

    // ---- 时间函数 ------------------------------------------------------------------------------

        int     GetCurrTime();
    
// ---- 函数实现 ----------------------------------------------------------------------------------


    /**********************************************************************************************
    *
    *   Init ()
    *
    *   初始化脚本系统
    */

    void Init ()
    {
        // 初始化脚本结构

        memset ( &g_Script, 0, sizeof(Script) );
    }

    /**********************************************************************************************
    *
    *   ShutDown ()
    *
    *   关闭脚本系统
    */

    void ShutDown ()
    {
        // ---- 释放指令流

        // 释放指令流元素

        for ( int iCurrInstrIndex = 0;
             iCurrInstrIndex < g_Script.InstrStream.iSize;
             ++ iCurrInstrIndex )
        {
            int iOpCount = g_Script.InstrStream.pInstrs [ iCurrInstrIndex ].iOpCount;
            Value *pOpList = g_Script.InstrStream.pInstrs [ iCurrInstrIndex ].pOpList;

            for( int iCurrOpIndex = 0;
                 iCurrOpIndex < iOpCount;
                 ++ iCurrOpIndex )
            {
                if ( pOpList [ iCurrOpIndex ].pstrStringLiteral != 0 && 
                    pOpList [ iCurrOpIndex ].iType == OP_TYPE_STRING )
                    delete pOpList [ iCurrOpIndex ].pstrStringLiteral;
            }
        }

        // 释放指令流本身

        delete g_Script.InstrStream.pInstrs;

        // ---- 释放运行时堆栈

        // 释放堆栈元素

        for ( int iCurrElmntIndex = 0;
              iCurrElmntIndex < g_Script.Stack.iSize;
              ++ iCurrElmntIndex )
        {
            if ( g_Script.Stack.pElements [ iCurrElmntIndex ].pstrStringLiteral != 0 &&
                 g_Script.Stack.pElements [ iCurrElmntIndex ].iType == OP_TYPE_STRING )
                delete g_Script.Stack.pElements [ iCurrElmntIndex ].pstrStringLiteral;
        }

        // 释放堆栈本身

        delete g_Script.Stack.pElements;

        // ---- 释放函数表

        if ( g_Script.pFuncTable )
            delete g_Script.pFuncTable;

        // ---- 释放主程序 API 调用表

        // 释放调用表中各个字符串

        for ( int iCurrCallIndex = 0;
              iCurrCallIndex < g_Script.HostAPICallTable.iSize;
              ++ iCurrCallIndex )
        {
            if( g_Script.HostAPICallTable.ppstrCalls [ iCurrCallIndex ] != 0 )
                delete g_Script.HostAPICallTable.ppstrCalls [ iCurrCallIndex ];
        }

        // 释放调用表本身

        if( g_Script.HostAPICallTable.ppstrCalls != 0 )
            delete g_Script.HostAPICallTable.ppstrCalls;
    }

    /**********************************************************************************************
    *
    *   LoadScript ()
    *
    *   装载脚本
    */

    int LoadScript ( char *pstrFileName )
    {
        // ---- 打开文件 

        FILE        * pScriptFile;
        fopen_s( &pScriptFile, pstrFileName, "rb" );
        if ( !pScriptFile )
            return LOAD_ERROR_FILE_IO; 

        // ---- 读取.zse文件头

        // 读取 ID 字符串(4字节)

        char    *pstrIDString   = new char[5];
        fread( pstrIDString, 4, 1, pScriptFile );
        pstrIDString [ strlen ( ZSE_ID_STRING ) ]    = '\0'; 
        g_iReadSize     += 4;

        // 检测 ID 字符串

        if( strcmp ( pstrIDString, ZSE_ID_STRING ) != 0 )
            return  LOAD_ERROR_INVALID_ZSE;
        delete  pstrIDString;

⌨️ 快捷键说明

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