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

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

    有兴趣可以下载看看哦: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

 

 
posted @ 2013-03-18 22:45  SF-_-  阅读(653)  评论(0编辑  收藏  举报