關 閉

        新聞中心

        EEPW首頁 > 工控自動化 > 設計應用 > COMET虛擬機的設計與實現

        COMET虛擬機的設計與實現

        作者: 時間:2012-07-10 來源:網絡 收藏

        2.8 調試器

        調試器是一個內嵌在里的機器級的調試器。當需要調試一個的程序時,只需要在啟動的時給出相應的命令參數就啟動調試功能了[2,4]。

        COMET調試器的基本功能有:顯示幫助(help),運行程序直到停止(go),分步執行(step n),跳轉程序(jump),顯示寄存器內容(regs),顯示內存數據(dMem),顯示內存指令(iMem),修改內存數據(alter),遍歷指令(trace),指令記數功能(print),重新裝載字節碼(clear),退出調試器(quit)。每個調試命令的具體用法可以參考COMET虛擬機的幫助文件。

        3 COMET虛擬機實現 3.1 虛擬機數據結構

        struct comet

        {

        off_t pc;

        short fr;

        short gr[5];

        short mem[MEMSIZE];

        } cmt;

        虛擬機結構變量cmt是一個全局變量,成員分別為:指令計數器(pc)、標志寄存器(fr)、通用寄存器(gr)、存儲器(mem)。將cmt設計為全局變量的優點是個函數不用傳遞復雜的結構體參數,缺點是每個進程同時只能有一個虛擬機實例。

        3.2 主函數

        int

        main(int argc, char *argv[])

        {

        init(argc, argv);

        if(debug) comet_debug();

        else while(comet_step());

        fclose(source);

        return 0;

        }

        函數init首先初始化COMET虛擬機并裝載字節碼,如果發生錯誤則停止。然后根據調試器狀態,選擇運行虛擬機的方式。如果調試開關(debug)被設置,則調用comet_debug函數在調試狀態下運行COMET虛擬機。如果沒有打開調試開關,則循環調用單步執行函數comet_step,直到程序結束[1,2]。

        3.3 字節碼載入

        void

        comet_load(void)

        {

        unsigned short n, flag[2];

        fseek(source, 0, SEEK_SET);

        n = fread(flag,

        sizeof(off_t), 2, source);

        n = fread(cmt.mem[flag[0]],

        sizeof(off_t),tmp[1],source);

        /* 其他處理代碼 */

        }

        變量n用于記錄讀取字節碼的數目,如果n小于相應的值,則發生字節碼裝載錯誤。變量flag用于保存字節碼裝載信息,分別字節碼裝載地址和字節碼大小。

        COMET字節碼設計比較簡單,也存在很多不足。例如,沒有標志文件格式的魔數,沒有更完善的錯誤檢測措施。我們的目的是讓讀者了解字節碼的工作原理,因此只給出了一種最簡單的實現[1,2,4]。

        3.4 指令解析

        指令的解析一般包含這個幾個過程:取指令,解碼,執行。其中解碼對虛擬機的執行效率有很大的影響[5]。這里采用下標索引技術來解碼指令。具體代碼如下:

        void comet_ld(void); /* LD指令*/

        void comet_ld(void); /*ST指令 */

        void comet_ld(void); /* LEA指令 */

        /* 其他指令函數聲明 */

        int comet_step(void)

        {

        static void (*comet_op)() = {

        comet_ld, comet_st, comet_lea,

        /* 其他指令執行函數指針 */

        };

        /* 解析指令,存放在op中 */

        short op = get_op();

        /* 執行op對應的代碼 */

        (*comet_op [op])();

        /* 返回執行狀態 */

        return val;

        }

        例如,有指令LEA,其對應的機器碼為031,那么將通過函數指針數組comet_op直接定位到(*comet_op[031])函數,即并執行相應的comet_lea函數。

        3.5 輸入輸出設備

        COMET虛擬機在解析每個指令前,先讀取IO設備狀態寄存器IO_FLAG中的值,如果IO_FLAG被設置,則執行相應的IO操作[3]。具體代碼如下:

        void

        comet_io(void)

        {

        switch(cmt.mem[IO_FLAG]IO_TYPE)

        {

        case IO_NULL:

        /* 無IO操作 */

        case IO_OCT IO_IN:

        /* 八進制輸入 */

        case IO_DEC IO_IN:

        /* 十進制輸入 */

        case IO_HEX IO_IN:

        /* 十六進制輸入 */

        case IO_OCT IO_OUT:

        /* 八進制輸出 */

        case IO_DEC IO_OUT:

        /* 十進制輸出 */

        case IO_HEX IO_OUT:

        /* 十六進制輸出 */

        default:

        /* 未知IO類型 */

        }

        /* 重置IO狀態寄存器IO_FLAG */

        }

        3.6 調試器

        調試程序是建立和單步執行的COMET虛擬機之上的。當沒有打開調試功能時,循環執行COMET虛擬機字節碼程序,直到停止。當打開了調試功能時,調試函數debug根據調試命令,執行相應步的指令、顯示或操作相關的數據。

        /* 各種調試命令 */

        typedef enum

        {

        GO, STEP, JUMP, REGS,

        IMEM, DMEM, ALTER,

        TRACE, PRINT, CLEAR,

        HELP, QUIT

        } DbType;

        /* 調試函數 */

        void

        comet_debug(void)

        {

        int cmd; /* 保存調試命令 */

        while(1) {

        /* 讀調試命令 */

        switch(cmd) {

        case HELP: /* 幫助文件 */

        case GO : /* 執行程序 */

        case STEP: /* 分步執行 */

        /* 其他調試命令 */

        default : /* 未知命令 */

        }

        }

        }

        調試函數comet_debug根據不同的調試命令執行相應的操作,并顯示虛擬機狀當前的狀態信息。

        4 運行虛擬機

        下面通過一個求(1 + 2 + … + n)的程序,來介紹其在COMET虛擬機上的執行的流程。程序的字節碼由相關的工具生成,保存為sum.comet文件(后綴為comet)。

        4.1 普通運行

        輸入命令:comet sum

        在COMET虛擬機獲得sum參數后,會自動識別為sum.comet字節碼文件。

        輸入100,表示求1+2+…+100的和。

        COMET虛擬機輸出:

        ===============

        COMET虛擬計算機

        存儲器相關文章:存儲器原理


        塵埃粒子計數器相關文章:塵埃粒子計數器原理


        關鍵詞: COMET 虛擬機

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 岳普湖县| 江川县| 巴塘县| 射洪县| 师宗县| 兴国县| 沙湾县| 丹江口市| 阿尔山市| 益阳市| 璧山县| 札达县| 云南省| 三都| 广河县| 达孜县| 霍州市| 贺兰县| 南部县| 抚州市| 辽阳县| 黄龙县| 东莞市| 鹰潭市| 博客| 邵阳县| 历史| 汕尾市| 普兰店市| 拉萨市| 孟津县| 靖边县| 卢湾区| 尼木县| 乌海市| 铜鼓县| 林州市| 娄底市| 鹤山市| 甘孜县| 独山县|