基于字符串的简单汇编虚拟机
上星期花了几天时间完成的,分离出来,然后~先贴一下图吧
有兴趣可以下载看看哦: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