Click here to Skip to main content
15,885,720 members
Articles / Containers / Virtual Machine
Article

A basic Virtual Machine for Experimentation

Rate me:
Please Sign up or sign in to vote.
1.10/5 (47 votes)
13 May 2003 69.8K   11   23
A basic Virtual Machine for experimentation.

Introduction

A rather QAD mini VM, for experimentation.

using System;
using System.Collections;

public class MiniVM {

   public static void Main(string [] args) {
    AVM vm = new AVM();

    String srcCode = "";
    srcCode += "           loadr 1 1;";
    srcCode += "loop:      cmpt  1 5 exit;";
    srcCode += "           sysPrint msg;";
    srcCode += "           incr  1 1;";
    srcCode += "           jump  loop;";
    srcCode += "exit:      brk;";
    srcCode += "msg:       data.string 'Hello World';";

    vm.asmCode(srcCode);

    vm.execCode();

   }
}

public class AVM {
    private byte []     vmc         = new byte[128];
    private Hashtable     lookupReplace     = new Hashtable();

    public void loadCode(byte [] newcode) {
        for ( int i = 0 ; i < newcode.Length ; i++ )
            vmc[i] = newcode[i];
    }

    private String [] getParms(String cLine) {
        String []     xparms     = cLine.Split(new char []{' '});
        String []     yparms     = new String[xparms.Length];
        int         parmCnt = 0;
        
        for ( int j = 0 ; j < xparms.Length ; j++ ) { // All this crap because String.Split includes extra tokens.
            if ( xparms[j] != String.Empty )
                yparms[parmCnt++] = xparms[j];
        }
        String [] parms = new String[parmCnt];
        Array.Copy(yparms, parms, parmCnt);

        return parms;
    }
    
    private int lookup(String sVal, int pc) {
        int v = -1;
        
        try { 
            v = Int16.Parse(sVal);
        } catch ( Exception e ) {
        }
        if ( v == -1 ) 
            lookupReplace.Add(pc, sVal);

        return v;
    }

    public void asmCode(String src) {
        String [] srcL = src.Split(new char [] {';'});
        asmCode(srcL);
    }
    
    public void asmCode(String [] src) {
        int pc = 0;
        Hashtable labels = new Hashtable();

        for ( int i = 0 ; i < src.Length ; i++ ) {
            if  ( src[i] == String.Empty ) continue;
            
            String         cLine     = src[i];
            String []     parms     = getParms(cLine);
            int         cmdPos     = 0;
            
            if ( parms[cmdPos].EndsWith(":") ) {
                labels.Add(parms[cmdPos].Substring(0, parms[cmdPos].Length-1), pc);
                cmdPos++;
            }
            
            switch ( parms[cmdPos] ) {
                case "sysPrint":
                    vmc[pc++] = 1;
                    int v = lookup(parms[cmdPos+1], pc);
                    vmc[pc++] = (byte)v;
                    break;
                case "brk":
                    vmc[pc++] = 0;
                    break;
                case "loadr":
                    vmc[pc++] = 2;
                    vmc[pc++] = (byte)(lookup(parms[cmdPos+1], pc));
                    vmc[pc++] = (byte)(lookup(parms[cmdPos+2], pc));
                    break;
                case "cmpt":
                    vmc[pc++] = 3;
                    vmc[pc] = (byte)(lookup(parms[cmdPos+1], pc));
                    pc++;
                    vmc[pc] = (byte)(lookup(parms[cmdPos+2], pc));
                    pc++;
                    vmc[pc] = (byte)(lookup(parms[cmdPos+3], pc));
                    pc++;
                    break;
                case "incr":
                    vmc[pc++] = 4;
                    vmc[pc++] = (byte)(lookup(parms[cmdPos+1], pc));
                    vmc[pc++] = (byte)(lookup(parms[cmdPos+2], pc));
                    break;
                case "jump":
                    vmc[pc++] = 5;
                    vmc[pc] = (byte)(lookup(parms[cmdPos+1], pc));
                    pc++;
                    break;
                case "data.string":
                    String x = cLine.Substring(cLine.IndexOf("data.string")+12);
                    //Console.WriteLine("LIT:"+x);
                    char [] c = x.ToCharArray();
                    for ( int j = 1 ; j < c.Length-1 ; j++ ) {
                        vmc[pc++] = (byte)(c[j]    );
                    }
                    vmc[pc++] = 0;
                    break;
            }
        }

        IDictionaryEnumerator myEnumerator = lookupReplace.GetEnumerator();
        while ( myEnumerator.MoveNext() ) {
             int val = (int)(labels[myEnumerator.Value]);
                 //Console.WriteLine("Sub {0} {1}", myEnumerator.Key, myEnumerator.Value+ " ="+val);
             vmc[(int)(myEnumerator.Key)] = (byte)val;
        }   

        //for ( int i = 0 ; i < pc ; i++ )
        //    Console.WriteLine(i+"::"+vmc[i]);
    }

    public void execCode() {
        int     pc     = 0;
        int     ilc     = 1;
        bool     cont     = true;
        int []     regs     = new int[16];
        
        while ( cont ) {
            byte currInst = vmc[pc];
            //Console.WriteLine(pc+":"+currInst+ "  ,  " + vmc[pc+1] + "  , " + vmc[pc+2]+ "  , " + vmc[pc+3]);
            switch ( currInst ) {
                case 0 : // brk
                    cont = false;
                    break;
                case 1 : // sysPrint
                    String p = "";
                    for ( int i = 0 ; vmc[vmc[pc+1]+i] != 0 ; i++ )
                        p += (char)(vmc[vmc[pc+1]+i]);
                    Console.WriteLine(p);
                    ilc = 2;
                    break;
                case 2 : // loadr
                    regs[vmc[pc+1]] = vmc[pc+2];
                    ilc = 3;
                    break;
                case 3 : // cmpt
                    if ( regs[vmc[pc+1]] == vmc[pc+2] ) {
                        pc = vmc[pc+3];
                        ilc = 0;
                    } else {
                        ilc = 4;
                    }
                    break;
                case 4 : // incr
                    regs[vmc[pc+1]] += vmc[pc+2];
                    ilc = 3;
                    break;
                case 5 : // jump
                    pc = vmc[pc+1];
                    ilc = 0;
                    break;
                default :
                    Console.WriteLine("UNK INST");
                    break;    
            }
            pc += ilc;
        }

    }
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Australia Australia
Just another nerd in a slowly drowning cluster of nerds in the vast technical ocean of our world.

Comments and Discussions

 
GeneralSuggestions to the author Pin
birman18-May-03 6:29
birman18-May-03 6:29 
GeneralStop the Bitchin! Pin
FruitBatInShades15-May-03 4:05
FruitBatInShades15-May-03 4:05 
GeneralRe: Stop the Bitchin! Pin
Anonymous15-May-03 4:39
Anonymous15-May-03 4:39 
GeneralRe: Stop the Bitchin! Pin
FruitBatInShades15-May-03 4:45
FruitBatInShades15-May-03 4:45 
GeneralRe: Stop the Bitchin! Pin
Include12315-May-03 16:05
Include12315-May-03 16:05 
GeneralRe: Stop the Bitchin! Pin
Taka Muraoka15-May-03 16:43
Taka Muraoka15-May-03 16:43 
GeneralRe: Stop the Bitchin! Pin
Include12315-May-03 16:58
Include12315-May-03 16:58 
QuestionWhat is the idea of this article ?! Pin
JP van Mackelenbergh14-May-03 19:41
JP van Mackelenbergh14-May-03 19:41 
It does not make sense to post an article with just some code. Every nerd can do that ...
Please try to type some comments and some more background info.
AnswerRe: What is the idea of this article ?! Pin
Anonymous14-May-03 19:48
Anonymous14-May-03 19:48 
GeneralRe: What is the idea of this article ?! Pin
JP van Mackelenbergh14-May-03 19:51
JP van Mackelenbergh14-May-03 19:51 
GeneralRe: What is the idea of this article ?! Pin
Anonymous14-May-03 21:00
Anonymous14-May-03 21:00 
GeneralRe: What is the idea of this article ?! Pin
Dr Herbie14-May-03 21:57
Dr Herbie14-May-03 21:57 
GeneralRe: What is the idea of this article ?! Pin
NormDroid14-May-03 23:06
professionalNormDroid14-May-03 23:06 
GeneralRe: What is the idea of this article ?! Pin
Philip Fitzsimons14-May-03 23:20
Philip Fitzsimons14-May-03 23:20 
GeneralRe: What is the idea of this article ?! Pin
NormDroid16-May-03 8:29
professionalNormDroid16-May-03 8:29 
GeneralRe: What is the idea of this article ?! Pin
Philip Fitzsimons16-May-03 12:19
Philip Fitzsimons16-May-03 12:19 
GeneralRe: What is the idea of this article ?! Pin
Anonymous15-May-03 1:51
Anonymous15-May-03 1:51 
GeneralRe: What is the idea of this article ?! Pin
Anatoly Ivasyuk15-May-03 5:20
Anatoly Ivasyuk15-May-03 5:20 
GeneralRe: What is the idea of this article ?! Pin
Include12315-May-03 15:57
Include12315-May-03 15:57 
GeneralRe: What is the idea of this article ?! Pin
Anatoly Ivasyuk16-May-03 10:05
Anatoly Ivasyuk16-May-03 10:05 
AnswerRe: What is the idea of this article ?! Pin
eric vincent15-May-03 2:43
eric vincent15-May-03 2:43 
GeneralRe: What is the idea of this article ?! Pin
Anonymous15-May-03 4:34
Anonymous15-May-03 4:34 
AnswerRe: What is the idea of this article ?! Pin
Chris Austin15-May-03 16:45
Chris Austin15-May-03 16:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.