当前位置: 首页 > news >正文

基于字符串的简单汇编虚拟机

    上星期花了几天时间完成的,分离出来,然后~先贴一下图吧

    有兴趣可以下载看看哦:http://pan.baidu.com/share/link?shareid=352033&uk=2804348991

    部分源代码:

VirtualMachine.cpp
#include "StdAfx.h"
#include "VirtualMachine.h"

VirtualMachine::VirtualMachine(void)
: Output(_T(""))
{
    //    初始化寄存器及堆栈
    memset(registers,0,32);
    memset(stack,0,sizeof(stack));
}

VirtualMachine::~VirtualMachine(void)
{
}

int VirtualMachine::runAsm(CString str,int &line)
{
    if(str.GetLength()<3)
        return 0;
    //    split up word
    int i=0;
    while(isalpha(str[i]))
        i++;
    CString order=str.Mid(0,i);
    CString one,two,three;
    if(str[i]==' ')
    {
        i++;
        int a=i;
        while(str[i]!=',' && str[i]!=0)
            i++;
        one=str.Mid(a,i-a);
        if(str[i]==',')
        {
            i++;
            int a=i;
            while(str[i]!=',' && str[i]!=0)
                i++;
            two=str.Mid(a,i-a);
            if(str[i]==',')
            {
                i++;
                int a=i;
                while(str[i]!=',' && str[i]!=0)
                    i++;
                three=str.Mid(a,i-a);
            }
        }
    }
    //    analysize the order
    if(order==L"mov")
    {
        this->setRegisterValue(one,this->getRegisterValue(two));
    }
    else if(order==L"add")
    {
        if(three==L"")
        {
            three=two;
            two=one;
        }
        this->setRegisterValue(one,this->getRegisterValue(two)+this->getRegisterValue(three));
    }
    else if(order==L"sub")
    {
        if(three==L"")
        {
            three=two;
            two=one;
        }
        this->setRegisterValue(one,this->getRegisterValue(two)-this->getRegisterValue(three));
    }
    else if(order==L"mul")
    {
        if(three==L"")
        {
            three=two;
            two=one;
        }
        this->setRegisterValue(one,this->getRegisterValue(two)*this->getRegisterValue(three));
    }
    else if(order==L"print")
    {
        Output.Format(L"%s\t%d",one,getRegisterValue(one));
        return 1;    //有输出值
    }
    else if(order==L"jmp")
    {
        line=this->getRegisterValue(one)-2;
    }
    else if(order==L"cmp")
    {
        int x=this->getRegisterValue(one);
        int y=this->getRegisterValue(two);
        if(x==y)
            ZF=0;
        else if(x>y)
            ZF=1;
        else
            ZF=-1;
    }
    else if(order==L"jge")
    {
        if(ZF!=-1)
            line=this->getRegisterValue(one)-2;
    }
    else if(order==L"jle")
    {
        if(ZF!=1)
            line=this->getRegisterValue(one)-2;
    }
    else if(order==L"jg")
    {
        if(ZF==1)
            line=this->getRegisterValue(one)-2;
    }
    else if(order==L"jl")
    {
        if(ZF==-1)
            line=this->getRegisterValue(one)-2;
    }
    else if(order==L"je")
    {
        if(ZF==0)
            line=this->getRegisterValue(one)-2;
    }
    else if(order==L"push")
    {
        stack[++esp]=this->getRegisterValue(one);
    }
    else if(order==L"pop")
    {
        this->setRegisterValue(one,stack[esp--]);
    }
    else if(order==L"call")
    {
        stack[++esp]=line;
        line=this->getRegisterValue(one)-2;
    }
    else if(order==L"retn")
    {
        line=stack[esp--];
    }
    else if(order=="end")
    {
        line=0x7FFFFFFE;
    }
    else
    {
        AfxMessageBox(L"I don't know");
    }
    return 0;    //    正常执行
}

int VirtualMachine::getRegisterValue(CString num)
{
    if(isdigit(num[0]))
    {
        int s=0;
        for(int i=0;i<num.GetLength();i++)
            s=s*10+(num[i]-'0');
        return s;
    }
    else if(num[0]=='e')
    {
        char a,b;
        a=(char)num[1];
        b=(char)num[2];
        int sum=registers[getRegisterAddress(num)];
        if(num.GetLength()>3)
            sum+=getRegisterValue(num.Mid(4))*(num[3]=='+'?1:-1);
        return sum;
    }
    else if(num[0]=='[')
    {
        return this->stack[this->getRegisterValue(num.Mid(1,num.GetLength()-2))];
    }
    AfxMessageBox(L"There may have a error~");
    return 0;
}

void VirtualMachine::setRegisterValue(CString reg,int num)
{
    if(reg[0]=='[')
        stack[getRegisterValue(reg.Mid(1,reg.GetLength()-2))]=num;
    else
        registers[getRegisterAddress(reg)]=num;
}

int VirtualMachine::getRegisterAddress(CString regName)
{
    char a=(char)regName[1];
    char b=(char)regName[2];
    return b=='x'?a-'a':((a=='s'?5:4)+(b=='i'?2:0));
}
VirtualMachine.h
#pragma once
#include "StdAfx.h"

class VirtualMachine
{
public:
    VirtualMachine(void);
    ~VirtualMachine(void);
private:
    //    define eight registers
    union
    {
        int registers[8];
        struct
        {
            int eax;    //    registers[0]
            int ebx;    //    registers[1]
            int ecx;    //    registers[2]
            int edx;    //    registers[3]
            int ebp;    //    registers[4]
            int esp;    //    registers[5]
            int edi;    //    registers[6]
            int esi;        //    registers[7]
        };
    };
    //    define a flag
    char ZF;
    //    define a stack;
    int stack[10000];
public:
    int runAsm(CString str,int &line);
    int getRegisterValue(CString num);
    void setRegisterValue(CString reg,int num);
    int getRegisterAddress(CString regName);
    CString Output;
};

测试代码:

mov eax,0
mov ecx,10
push ecx
call fun
pop ecx
print eax
end

fun:
cmp [esp-1],0
je fend
mov edx,[esp-1]
add eax,eax,edx
sub edx,edx,1
push edx
call fun
pop ecx
fend:
retn

 

 

转载于:https://www.cnblogs.com/IT-BOY/archive/2013/03/18/2966966.html

相关文章:

  • 快速升级Oracle 11.2.0.2 RAC到11.2.0.3
  • SQL如何在已有的一张表中插入一列类型为INTEGER数据 并赋初始值为0
  • sublime text 3
  • 木杉大话微软手机系统
  • Python Dict 创建
  • 如何在存储过程内部调用另一个存储过程 EXEC
  • 翻转句子中单词的顺序
  • 转 MapGuide HTTP API
  • 倍压整流电路
  • Tomcat中对内存的分配与溢出的处理办法
  • 一个VR 开发工具SDK
  • 关系型数据库基础之:关系型数据库管理系统简介
  • tomcat 随笔小记
  • 反射学习入门篇 (三)--Emit的使用
  • 累赘的shell
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • css系列之关于字体的事
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • JAVA 学习IO流
  • JavaScript的使用你知道几种?(上)
  • Java编程基础24——递归练习
  • jdbc就是这么简单
  • jquery cookie
  • LeetCode29.两数相除 JavaScript
  • Mybatis初体验
  • mysql_config not found
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • Python 基础起步 (十) 什么叫函数?
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 前端相关框架总和
  • 如何合理的规划jvm性能调优
  • 手机端车牌号码键盘的vue组件
  • 用element的upload组件实现多图片上传和压缩
  • 自定义函数
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • ​​​​​​​​​​​​​​Γ函数
  • !$boo在php中什么意思,php前戏
  • # Panda3d 碰撞检测系统介绍
  • (10)STL算法之搜索(二) 二分查找
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (独孤九剑)--文件系统
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (四)鸿鹄云架构一服务注册中心
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转载)利用webkit抓取动态网页和链接
  • *Django中的Ajax 纯js的书写样式1
  • .Net Web窗口页属性
  • .NET 服务 ServiceController
  • .net 使用ajax控件后如何调用前端脚本
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .NET单元测试
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解