Hello all, I will be placing my source code onto pastebin and making it private as I am scared of my fellow students stealing my hard work for this class.

So far I have about 1000 lines of code that is pretty easy to understand and it compiles and runs properly for the first TWO sample programs.

However, the FINAL problem, the fact.s sample problem does not work. I get a final value of 0 for the factorial always no matter what input value I give. I have stepped through the program and I always lose it when it goes into recursion. I have tried over and over to see what it is doing throughout the program, and I have lost sleep for two nights now.
I hope anyone here can help me I have worked so hard and I will only get a 70% if I turn it in like this :(

There are random couts spread around and several commented lines these are for troubleshooting the program as it runs.

FULL instructions on the project can be found here: http://www.csci.csusb.edu/kay/cs460/phase1.html


Here is all my source code:
Assembler.h http://pastebin.com/F67fm7N0
Virtualmachine.h http://pastebin.com/i7z46BwF
Assembler.cpp http://pastebin.com/BbHd68Fb
Virtualmachine.cpp http://pastebin.com/5f5YPXdg
os.cpp http://pastebin.com/bghErqF1
prog.s http://pastebin.com/b674kxLA
prog.in http://pastebin.com/JKxqy6nK

>> Hello all, I will be placing my source code onto pastebin and making it private as I am scared of my fellow students stealing my hard work for this class.

Sort of defeats the purpose of the forum if...

  1. You don't post the code here.
  2. You make it private.

That's sort of like helping via PM. It helps you, but no one else.

Do you really want me to paste 1000 lines here? Just click the links to pastebin and you will see all the code :)

I will paste it all here if you want... "private" does not mean it is completely private it just means you need the LINK which I have posted above :)

Either way... here we goooo....

ASSEMBLER.H

/******************************************************************************
    Filename: Assembler.h
    By: Matthew DeBord and Ronald Radut
    Created: 04/11/2011
    Last Modified: 04/20/2011
    Description: This header contains class declarations for the Assembler
    ******************************************************************************/
     
     
     
    #include <cstdlib>  // for exit()
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>  // for istringstream
    #include <vector>
    using namespace std;
     
    class Assembler {
            private:
                    string line, opcode;
                    int rd, rs, constant, address, optemp, imm;
                    void defineInst(string line); // takes line from getLine and parses it to define the instruction
                    int buildFormat1(int opcode, int rd, int rs, int imm);
                    int buildFormat2(int opcode, int rd, int imm, int tail);
     
            public:
                    Assembler();
                    vector<int> v;
                    void assemble(); // grabs a line from the .s file and sends it to defineInst(), line by line until eof.
    };

ASSEMBLER.CPP

/******************************************************************************
    Filename: Assembler.cpp
    By: Matthew DeBord and Ronald Radut
    Created: 04/11/2011
    Last Modified: 04/20/2011
    Description: This cpp code builds and executes the
    assembler turning our .s to .o
    ******************************************************************************/
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include "Assembler.h"
    using namespace std;
     
    Assembler::Assembler()
    {
            this->rd=-1;
            this->rs=-1;
            this->constant=-129;
    }
    void Assembler::assemble()
    {
            fstream assemblyProg;
            assemblyProg.open("prog.s", ios::in);
            if (!assemblyProg.is_open()) {
            cout << "prog.s failed to open.\n";
            exit(1);
            }
     
            getline(assemblyProg, this->line);
            while (!assemblyProg.eof())
            {
                    defineInst(this->line); // send line to defineInst to be parsed
                    getline(assemblyProg, this->line);
            }
            assemblyProg.close();
     
            fstream outFile;
            outFile.open("prog.o", ios::out);
            for (int i=0;i<v.size();i++)
                    {
                    outFile << v[i] << endl; // write each instruction to a new line in the prog.o file.
                    }
            outFile.close();
    }
    void Assembler::defineInst(string line)
    {
                    istringstream str(line.c_str()); //convert to c-string
                    str >> opcode;
                    if (opcode!="!")
                    {
                            if (opcode == "load")
                            {
                                    optemp = 0;
                                    imm = 0;
                                    str >> rd >> address;  
                                    int instruction = buildFormat2(optemp, rd, imm, address);
                                    v.push_back(instruction);
                            }
     
     
                            else if (opcode == "loadi")
                            {
                                    optemp = 0;
                                    imm = 1;
                                    str >> rd >> constant;
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
     
                            else if (opcode == "store")
                            {
                                    optemp = 1;
                                    imm = 0;
                                    str >> rd >> address;
                                    int instruction = buildFormat2(optemp, rd, imm, address);
                                    v.push_back(instruction);
                            }    
     
                            else if (opcode == "add")
                            {
                                    optemp = 2;
                                    imm = 0;
                                    str >> rd >> rs;
                                    int instruction = buildFormat1(optemp, rd, rs, imm);
                                    v.push_back(instruction);
                            }    
     
                            else if (opcode == "addi") //set carry
                            {
                                    optemp = 2;
                                    imm = 1;
                                    str >> rd >> constant;
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
     
                            else if (opcode == "addc") //set carry
                            {
                                    optemp = 3;
                                    imm = 0;    
                                    str >> rd >> rs;
                                    int instruction = buildFormat1(optemp, rd, rs, imm);
                                    v.push_back(instruction);
                            }
     
                            else if (opcode == "addci") //set carry
                            {
                                    optemp = 3;
                                    imm = 1;  
                                    str >> rd >> constant;
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
     
                            else if (opcode == "sub") //set carry
                            {
                                    optemp = 4;
                                    imm = 0;  
                                    str >> rd >> rs;
                                    int instruction = buildFormat1(optemp, rd, rs, imm);
                                    cout << instruction;
                            }
                            else if (opcode == "subi") //set carry
                            {
                                    optemp = 4;
                                    imm = 1;
                                    str >> rd >> constant;
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "subc") //set carry
                            {
                                    optemp = 5;
                                    imm = 0;  
                                    str >> rd >> rs;
                                    int instruction = buildFormat1(optemp, rd, rs, imm);
                                    cout << instruction;
                            }
                            else if (opcode == "subci") //set carry
                            {
                                    optemp = 5;
                                    imm = 1;
                                    str >> rd >> constant;
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "and")
                            {
                                    optemp = 6;
                                    imm = 0;
                                    str >> rd >> rs;
                                    int instruction = buildFormat1(optemp, rd, rs, imm);
                                    cout << instruction;
                            }
                            else if (opcode == "andi")
                            {
                                    optemp = 6;
                                    imm = 1;
                                    str >> rd >> constant; 
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "xor")
                            {
                                    optemp = 7;
                                    imm = 0;
                                    str >> rd >> rs;
                                    int instruction = buildFormat1(optemp, rd, rs, imm);
                                    cout << instruction;
                            }
                            else if (opcode == "xori")
                            {
                                    optemp = 7;
                                    imm = 1;
                                    str >> rd >> constant;
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "compl")
                            {
                                    optemp = 8;
                                    imm = 0;
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "shl") //set carry
                            {
                                    optemp = 9;
                                    imm = 0;  
                                    str >> rd;     
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "shla") //set carry and sign extend
                            {
                                    optemp = 10;
                                    imm = 0;
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "shr") //set carry
                            {
                                    optemp = 11;
                                    imm = 0;                    
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "shra") //set carry and sign extend
                            {
                                    optemp = 12;
                                    imm = 0;                    
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "compr")
                            {
                                    optemp = 13;
                                    imm = 0;
                                    str >> rd >> rs;
                                    int instruction = buildFormat1(optemp, rd, rs, imm);
                                    cout << instruction;
                            }
                            else if (opcode == "compri")
                            {
                                    optemp = 13;
                                    imm = 1;                    
                                    str >> rd >> constant;
                                    int instruction = buildFormat2(optemp, rd, imm, constant);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "getstat")
                            {
                                    optemp = 14;
                                    imm = 0;
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "putstat")
                            {
                                    optemp = 15;
                                    imm = 0;                    
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "jump")
                            {
                                    optemp = 16;
                                    imm = 0;                    
                                    str >> address;
                                    int instruction = buildFormat2(optemp, rd, imm, address);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "jumpl")
                            {
                                    optemp = 17;
                                    imm = 0;                    
                                    str >> address;
                                    int instruction = buildFormat2(optemp, rd, imm, address);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "jumpe")
                            {
                                    optemp = 18;
                                    imm = 0;                    
                                    str >> address;
                                    int instruction = buildFormat2(optemp, rd, imm, address);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "jumpg")
                            {
                                    optemp = 19;
                                    imm = 0;                    
                                    str >> address;
                                    int instruction = buildFormat2(optemp, rd, imm, address);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "call")
                            {
                                    optemp = 20;
                                    imm = 0;                    
                                    str >> address;
                                    int instruction = buildFormat2(optemp, rd, imm, address);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "return")
                            {
                                    optemp = 21;
                                    imm = 0;
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "read")
                            {
                                    optemp = 22;
                                    imm = 0;
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "write")
                            {
                                    optemp = 23;
                                    imm = 0;    
                                    str >> rd;
                                    int instruction = buildFormat2(optemp, rd, imm, 0);
                                    v.push_back(instruction);
                            }
                            else if (opcode == "halt")
                            {
                                    optemp = 24;
                                    imm = 0;
                                    optemp = optemp << 11;
                                    int instruction = optemp;
                                    v.push_back(instruction);
                            }
                            else if (opcode == "noop")
                            {
                                    optemp = 25;
                                    imm = 0;
                                    optemp = optemp << 11;
                                    int instruction = optemp;
                                    v.push_back(instruction);
                            }
     
                            else
                            {
                                    cout << "OPCODE:" << opcode << " is unkown." << endl << "Press any key to exit." << endl;
                                    cin.get();
                                    exit(1);
                            }
                    }
    }
    int Assembler::buildFormat1(int opcode, int rd, int rs, int imm)
    {
            if (rd<0||rd>3||rs<0||rs>3) // error checking for legal register values
                    {
                            cout << "Invalid register" << endl << "Press any key to exit";
                            cin.get();
                            exit(1);
                    }
            int finalvalue;
            opcode = opcode <<11; // begin bit shifts
            rd = rd << 9;
            rs = rs << 6;
            imm = imm << 8;
            finalvalue = opcode+rd+rs+imm;
            return finalvalue;
    }
    int Assembler::buildFormat2(int opcode, int rd, int imm, int tail)
    {
            if (rd<0||rd>3) // error checking for legal register values
                    {
                            cout << "Invalid register" << endl << "Press any key to exit";
                            cin.get();
                            exit(1);
                    }
            int finalvalue;
            opcode = opcode << 11; // begin bit shifts
            rd = rd << 9;
            imm = imm << 8;
            if (tail<0) // must use masking to get the final 2's compliment value inserted to rightmost 8 bits of instruction.
                    {
                    finalvalue = opcode+rd+imm;
                    finalvalue = finalvalue + 255;
                    finalvalue = tail&finalvalue;
                    }
            else
                    {
                    finalvalue = opcode+rd+imm+tail;
                    }
            return finalvalue;
    }

VIRTUALMACHINE.H

/******************************************************************************
    Filename: VirtualMachine.h
    By: Matthew DeBord and Ronald Radut
    Created: 04/11/2011
    Last Modified: 04/20/2011
    Description: This header contains class declarations for the Virtual Machine
    ******************************************************************************/
     
     
    #include <cstdlib>  
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <sstream>
    using namespace std;
     
    // following format classes property of K Zemoudeh
    class format1 {
            public:
                    unsigned UNUSED:6;
                    unsigned RS:2;
                    unsigned I:1;
                    unsigned RD:2;
                    unsigned OP:5;
            };
    class format2 {
            public:
                    unsigned ADDR:8;
                    unsigned I:1;
                    unsigned RD:2;
                    unsigned OP:5;
            };
    class format3 {
            public:
                    int CONST:8;
                    unsigned I:1;
                    unsigned RD:2;
                    unsigned OP:5;
            };
    union instruction {
                    int i;
                    format1 f1;
                    format2 f2;
                    format3 f3;
            };
     
    // Begin Virtual Machine Class
    class VirtualMachine
    {
                            private:
                                    static const int REG_FILE_SIZE = 4;
                    static const int MEM_SIZE = 256;
                    vector<int> r;
                    vector<int> mem;
                                    string line;
                                    unsigned int ir, pc, sr, sp, clock, base, limit;
                                   
                                    //sign extender
                                    int signExtend(int i);
     
                                    // following functions set the corresponding bit for the sr
                                    void setV(int i);
                                    void setL(int i);
                                    void setE(int i);
                                    void setG(int i);
                                    void setC(int i);
     
                                    //following functions GET the corresponding bit from sr
                                    int getV();
                                    int getL();
                                    int getE();
                                    int getG();
                                    int getC();
     
                                    bool checkOverflow(int a, int b);
                                    bool checkOverflow3(int a, int b, int c);
                                    bool checkOverflow1(int a);
                                    // need base/limit registers??  <--- ATTN <----
     
               public:
                               VirtualMachine();
                               void Execute();
                               
    };

VIRTUALMACHINE.CPP

/******************************************************************************
    Filename: VirtualMachine.cpp
    By: Matthew **** and Ronald ****
    Created: 04/11/2011
    Last Modified: 04/25/2011
    Description: This cpp code creates and executes our VirtualMachine class
    ******************************************************************************/
     
    #include <cstdlib>  
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <sstream>
    #include "VirtualMachine.h"
    using namespace std;
     
    // Begin Member Functions //
     
    VirtualMachine::VirtualMachine()
    {
            for (int i=0;i<MEM_SIZE;i++) // construct memory vector
            {
                    mem.push_back(0);
            }
            for (int i=0;i<REG_FILE_SIZE;i++) // construct register vector
            {
                    r.push_back(0);
            }
            this->pc=0;
            this->sr=0;
            this->clock=0;
            this->base=0;
            this->sp=MEM_SIZE;
            fstream infile;
            infile.open("prog.o", ios::in);
            if (!infile.is_open())
            {
                    cout << "prog.o failed to open.\n";
                    exit(1);
            }
            getline(infile, this->line);
     
            int temp;
            int iterator=0;
     
            while (!infile.eof())
            {
                    istringstream str(line.c_str()); //convert to c-string
                    temp=0;
                    str >> temp;
                    mem[iterator]=temp; // insert value into memory vector, filling it with instructions.
                    iterator++;
                    this->limit=iterator;
                    getline(infile, this->line);
            }
     
     
     
            infile.close();
            Execute(); // construction finished, begin execution.
    }
     
    // sign extender
    int VirtualMachine::signExtend(int i)
    {
            unsigned bits=16; // extend to 16 bits
            int extended;      // output
            int const mask = 32768; // mask
            i = i & ((1U << bits) - 1);
            extended = (i ^ mask) - mask;
            //cout << extended;
            return extended;
    }
     
    // Set SR bits to 0 or 1
    void VirtualMachine::setV(int i)
    {
            i=i<<4;
            sr = sr&15; // mask to clear the V location to 0;
            sr = sr+i;  // insert new V value into sr.
    }
    void VirtualMachine::setL(int i) // set less
    {
            i=i<<3;
            sr = sr&23; // mask to clear the current L
            sr = sr+i;
    }
    void VirtualMachine::setE(int i)
    {
            i=i<<2;
            sr = sr&27; // clear current E
            sr = sr+i;
    } //
    void VirtualMachine::setG(int i)
    {
            i=i<<1;
            sr = sr&29; // clear current G
            sr = sr+i;
    }
    void VirtualMachine::setC(int i)
    {
            i=i<<0;
            sr = sr&30; // clear current C
            sr = sr+i;
    }
     
    // Get SR bits, return 1 if given bit was active
    int VirtualMachine::getV()
    {
            int j = sr&16; // mask to isolate bit
            if (j==16)
            {
                    return 1;
            }
            else
            {
                    return 0;
            }
    }
    int VirtualMachine::getL()
    {
            int j = sr&8; // mask to isolate bit
            if (j==8)
            {
                    return 1;
            }
            else
            {
                    return 0;
            }
    }
    int VirtualMachine::getE()
    {
            int j = sr&4; // mask to isolate bit
            if (j==4)
            {
                    return 1;
            }
            else
            {
                    return 0;
            }
    }
    int VirtualMachine::getG()
    {
            int j = sr&2; // mask to isolate bit
            if (j==2)
            {
                    return 1;
            }
            else
            {
                    return 0;
            }
    }
    int VirtualMachine::getC()
    {
            int j = sr&1; // mask to isolate bit
            if (j==1)
            {
                    return 1;
            }
            else
            {
                    return 0;
            }
    }
     
    bool VirtualMachine::checkOverflow(int a, int b)
    {
            if (a+b>=65536)
            {
                    return true;
            }
            else
            {
                    return false;
            }
    }
    bool VirtualMachine::checkOverflow3(int a, int b, int c)
    {
            if (a+b+c>=65536)
            {
                    return true;
            }
            else
            {
                    return false;
            }
    }
    bool VirtualMachine::checkOverflow1(int a)
    {
            if (a>=65536)
            {
                    return true;
            }
            else
            {
                    return false;
            }
    }
     
    // Begin Processing of Instructions
    void VirtualMachine::Execute()
    {
            instruction ins;
            int constant, addr, imm, carry, rs, rd, opcode;
     
            while(true) // MUST CHANGE to INFINITE LOOP
            {
                    ir = mem[pc]; // Set the current instruction to be processed.
                    ins.i = ir; // for parsing with format classes
                    pc++; // pc always gets incremented.
                    carry = getC(); // carry is always set each operation
     
                    // gather opcode, imm, rd, rs, constant, and addr for processing.
                    opcode = ins.f1.OP;
                    imm = ins.f1.I;
                    rd = ins.f1.RD;
                    rs = ins.f1.RS;
                    constant = ins.f3.CONST;
                    addr = ins.f2.ADDR;
     
                    // **** TEST PURPOSES, remove later. *****
                    cout << "opcode: " << opcode << " rd: " << rd << " rs: " << rs << " constant: " << constant << " address: " << addr << " r0 " << r[0] <<  " r1 " << r[1] <<  " r2 " << r[2] <<  " r3 " << r[3] << endl;
                   
                    // end test
     
     
                    if (constant < 0)
                    {
                            constant = signExtend(constant);
                    }
                    else
                    {}
     
     
                    if (opcode==0)
                    {      
                            if (imm==0) // load RD ADDR
                            {
                                    r[rd] = mem[addr]; // load contents of mem[address] into r[rd]
                            }
                            else // loadi RD CONST
                            {
                                    r[rd] = constant; // load direct value into r[rd]
                            }
                    }
     
     
                    else if (opcode==1) //store
                    {
                            mem[addr] = r[rd];
                            clock=clock+4;
                    }
     
                    else if (opcode==2)
                    {       clock++;
     
                    if (imm==0) // add RD RS
                    {
                            if (checkOverflow(r[rd], r[rs])==true)
                            {
                                    setC(1); // set carry if overflowed
                                    r[rd] = r[rd] + r[rs]; //add
                            }
                            else
                            {
                                    setC(0);
                                    r[rd] = r[rd] + r[rs]; //add
                            }
                    }
                    else
                    {
                            if (checkOverflow(r[rd], constant)==true)
                            {
                                    setC(1); // set carry if overflowed
                                    r[rd] = r[rd] + constant;
                            }
                            else
                            {
                                    setC(0);
                                    r[rd] = r[rd] + constant;
                            }
                    }
                    }
     
                    else if (opcode==3)
                    {
                            clock++;
                            if (imm==0) // addc RD RS
                            {
                                    if (checkOverflow3(r[rd], r[rs], carry)==true)
                                    {
                                            setC(1); // set carry if overflowed
                                            r[rd] = r[rd] + r[rs] + carry; //add
                                    }
                                    else
                                    {
                                            setC(0);
                                            r[rd] = r[rd] + r[rs] + carry; //add
                                    }
     
                            }
                            else
                            {      
                                    if (checkOverflow3(r[rd], constant, carry)==true)
                                    {
                                            setC(1); // set carry if overflowed
                                            r[rd] = r[rd] + constant + carry; //add
                                    }
                                    else
                                    {
                                            setC(0);
                                            r[rd] = r[rd] + constant + carry; //add
                                    }              
                            }
     
                    }
     
     
     
                    else if (opcode==4)
                    {
                            if (imm==0)
                            {
                                    if(checkOverflow(rd, rs)==true)
                                    {
                                            setC(1);
                                            r[rd] = r[rd] - r[rs];
                                    }
                                    else
                                    {
                                            setC(0);
                                            r[rd] = r[rd] - r[rs];
                                    }
                                    clock++;
                                   
                            }
                            else
                            {
                                    if(checkOverflow(rd, rs)==true)
                                    {
                                            setC(1);
                                            r[rd] = r[rd] - constant;
                                    }
                                    else
                                    {
                                            setC(0);
                                            r[rd] = r[rd] - constant;
                                    }
                                    clock++;       
                            }
                    }
     
                    else if (opcode==5)
                    {
                            if (imm==0)
                            {
                                    if(checkOverflow(rd, rs)==true)
                                    {
                                    setC(1);
                                    r[rd] = r[rd] - r[rs] - carry;
                                    }
                                    else
                                    {
                                            setC(0);
                                            r[rd] = r[rd] - r[rs] - carry;
                                    }
                                    clock++;
                                   
                            }
                            else
                            {
                                    if(checkOverflow(rd, rs)==true)
                                    {
                                            setC(1);
                                            r[rd] = r[rd] - constant - carry;
                                    }
                                    else
                                    {
                                            setC(0);
                                            r[rd] = r[rd] - constant - carry;
                                    }
                                    clock++;
                                    }
                    }
     
     
                    else if (opcode==6)
                    {
                            if (imm==0)
                            {
                                    r[rd] = r[rd] & r[rs];
                                    clock++;
                            }
                            else
                            {
                                    r[rd] = r[rd] & constant;
                                    clock++;
                            }
                    }
     
                    else if (opcode==7)
                    {
                            if (imm==0)
                            {
                                    r[rd] = r[rd] ^ r[rs];
                                    clock++;
                            }
                            else
                            {
                                    r[rd] = r[rd] ^ constant;
                                    clock++;
                            }
                    }
     
                    else if (opcode==8) // negate value of r[rd]
                    {
                            r[rd] = r[rd] * -1;
                            clock++;
                    }
     
                    else if (opcode==9) //shl
                    {
                            if (r[rd]>1)
                            {
                            r[rd] = r[rd] << 1;
                            }
                            else{}
     
                            if(checkOverflow1(r[rd])==true)
                            {
                                    setC(1);
                            }
                            else
                            {
                                    setC(0);
                            }
                            clock++;
                    }
     
                    else if (opcode==10) //shl
                    {
                            r[rd] = r[rd] << 1;
                            if(checkOverflow1(r[rd])==true)
                            {
                                    setC(1);
                            }
                            else
                            {
                                    setC(0);
                            }
                            signExtend(r[rd]);
                            clock++;
                    }
     
                    else if (opcode==11)
                    {
                            r[rd] = r[rd] >> 1;
                            if(checkOverflow1(r[rd])==true)
                            {
                                    setC(1);
                            }
                            else
                            {
                                    setC(0);
                            }
                            clock++;
                    }
                   
     
                    else if (opcode==12)
                    {
                            r[rd] = r[rd] >> 1;
                            if(checkOverflow1(r[rd])==true)
                            {
                                    setC(1);
                            }
                            else
                            {
                                    setC(0);
                            }
                            signExtend(r[rd]);
                            clock++;
                    }
     
                    else if (opcode==13) // set bits in sr based on comparing registers
                    {
                            if (imm==0)
                            {
                                    if (r[rd] < r[rs])
                                    {
                                            setL(1); // set less bit and reset rest.
                                            setE(0);
                                            setG(0);
                                            clock++;
                                    }
                                    else if (r[rd] == r[rs])
                                    {
                                            setL(0);
                                            setE(1); // set equal bit and reset rest
                                            setG(0);
                                            clock++;
                                    }
                                    else if (r[rd] > r[rs])
                                    {
                                            setL(0);
                                            setE(0);
                                            setG(1); // set greater bit and reset rest
                                            clock++;
                                    }
                            }
                            else
                            {
                                    if (r[rd] < constant)
                                    {
                                            setL(1); // set less bit and reset rest.
                                            setE(0);
                                            setG(0);
                                            clock++;
                                    }
                                    else if (r[rd] == constant)
                                    {
                                            setL(0);
                                            setE(1); // set equal bit and reset rest
                                            setG(0);
                                            clock++;
                                    }
                                    else if (r[rd] > constant)
                                    {
                                            setL(0);
                                            setE(0);
                                            setG(1); // set greater bit and reset rest
                                            clock++;
                                    }
                                    else {}
     
                            }
                    }
     
                    else if (opcode==14) //save sr into the given register
                    {
                            r[rd] = this->sr;
                            clock++;
                    }
     
                    else if (opcode==15) //putstat (sr=rd) sets the status register=given register
                    {
                            this->sr = r[rd];
                            clock++;
                    }
                    else if (opcode==16) //jump
                    {
                            this->pc = addr;
                            clock++;
                    }
                    else if (opcode==17) //jump if less
                    {
                            int j = getL(); // returns 1 if LESS was set
                            if (j==1)
                            {
                                    pc = addr;
                                    clock++;
                            }
                            else{}
     
                    }              
                    else if (opcode==18) //jump if equal
                    {
                            int j = getE(); // returns 1 if EQUAL was set
                            if (j==1)
                            {
                                    pc = addr;
                                    clock++;
                            }                      
                    }              
                    else if (opcode==19) //jump if greater
                    {
                            int j = getG(); // returns 1 if GREATER was set
                            if (j==1)
                            {
                                    pc = addr;
                                    clock++;
                            }
                            else{}
                    }              
                    else if (opcode==20) //CALL pc=addr .... push vm status (rd, sr, r0,r1,r2,r3)
                    {
     
                            if(sp<limit+6)
                            {
                                    cout << "ERROR STACK FULL!!";
                                    cout << endl << "Cannot perform CALL operation, press Enter to continue";
                                    cin.get();
     
                            }
                            else //push VM status onto stack
                            {
                                    mem[sp-1]=pc;
                                    mem[sp-2]=sr;
                                    mem[sp-3]=r[0];
                                    mem[sp-4]=r[1];
                                    mem[sp-5]=r[2];
                                    mem[sp-6]=r[3];
                                    this->sp=sp-6; // set new stack pointer
                                    clock=clock+4;
                                    pc=addr;
                            }      
                    }
     
                    else if (opcode==21) // return
                    {
                            if (sp>=MEM_SIZE)
                            {
                                    // stack is empty, nothing to pop.
                            }
                            else
                            {
                                    // load values stored in memory to pc, sr, r0, r1, r2, r3
                                    pc=mem[sp+5];
                                    cout << pc<< endl;
                                    sr=mem[sp+4];
                                    r[0]=mem[sp+3];
                                    r[1]=mem[sp+2];
                                    r[2]=mem[sp+1];
                                    r[3]=mem[sp];
     
                                    //pop used values off the stack
                                    mem[sp+5]=0;
                                    mem[sp+4]=0;
                                    mem[sp+3]=0;
                                    mem[sp+2]=0;
                                    mem[sp+1]=0;
                                    mem[sp]=0;
     
                                    if(sp<MEM_SIZE-6)
                                    {
                                            sp=sp+6; // set new stack pointer
                                    }
                                    else
                                    {
                                            sp=MEM_SIZE;
                                    }
                            }
     
                            clock=clock+4;
                    }      
     
                    else if (opcode==22) //read new content of r[rd] from .in file
                    {
                            clock=clock+28;
                            fstream inputfile;
                            inputfile.open("prog.in", ios::in);
                            if (!inputfile.is_open())
                            {
                                    cout << "prog.in failed to open.\n";
                            }
                            else
                            {
                                    int temp;
                                    inputfile>>temp;
                                    r[rd]=temp; // insert new value into r[rd]
                                    inputfile.close();
                            }
                    }
     
     
     
     
                    else if (opcode==23) //write r[rd] into .out file
                    {
                            fstream outputfile;
                            outputfile.open("prog.out", ios::out);
                            if (!outputfile.is_open())
                            {
                                    cout << "could not create prog.o .\n";
                            }
                            else
                            {
                                    outputfile<<"Register Value: "<<r[rd]<<endl;
                                    outputfile<<"R0 Value: "<<r[0]<<endl;
                                    outputfile<<"R1 Value: "<<r[1]<<endl;
                                    outputfile<<"R2 Value: "<<r[2]<<endl;
                                    outputfile<<"R3 Value: "<<r[3]<<endl;
                                   
                                    outputfile.close();
                            }
                            clock=clock+28;
                    }      
     
                    else if (opcode==24)
                    {
                            clock++;
     
                            //write final clock value when program halts
                            fstream outputfile;
                            outputfile.open("prog.out", ios::app); //append
                            if (!outputfile.is_open())
                            {
                                    cout << "could not create/open prog.o .\n";
                            }
                            else
                            {
                                    outputfile<<"Clock: "<<clock<<endl;
                                    outputfile.close();
                            }
                            //cin.get();
                            //cout<<"add 5: "<<mem[8];
                            cout << mem[33] << "   " << mem[34] << "  " << mem[35]<<endl;
                            cin.get(); // pause
                            exit(0);
                    }      
                    else if (opcode==25)
                    {
                            //noop
                            clock++;
                    }      
     
            }
     
    }

PROG.S

! main for factorial program
    loadi  0 1     ! line 0, R0 = fact(R1)
    read   1       ! input R1
    call   6       ! call fact
    load   0 33    ! receive result of fact
    write  0
    halt
    ! fact function
    compri 1 1     ! line 6
    jumpe  14      ! jump over the recursive call to fact if
    jumpl  14      ! R1 is less than or equal 1
    call   16      ! call mult (R0 = R0 * R1)
    load   0 34    ! receive result of mult
    subi   1 1     ! decrement multiplier (R1) and multiply again
    call   6       ! call fact
    load   0 33
    store  0 33    ! line 14, return R0 (result of fact)
    return
    ! mult function
    loadi  2 8     ! line 16, init R2 (counter)
    loadi  3 0     ! init R3 (result of mult)
    shr    1       ! line 18 (loop), shift right multiplier set CARRY
    store  2 35    ! save counter
    getstat 2      ! to find CARRY's value        
    andi   2 1
    compri 2 1
    jumpe  25      ! if CARRY==1 add
    jump   26      ! otherwise do nothing
    add    3 0
    shl    0       ! make multiplicand ready for next add
    load   2 35    ! restore counter
    subi   2 1     ! decrement counter        
    compri 2 0     ! if counter > 0 jump to loop
    jumpg  18
    store  3 34    ! return R3 (result of mult)
    return
    noop           ! line 33, fact return value
    noop           ! line 34, mult return value
    noop           ! line 35, mult counter

PROG.IN

2

Edited 5 Years Ago by noobcoder: n/a

Actually I was thinking you should possibly post the code as an attachment, maybe tarred with a makefile, sample file, expected output, etc. Just post the relevant code that pertains to the problem in the actual post itself. Can you summarize the exact problem you're having? Zero us in on a line number? Where's the "fact.s" program that's failing. It's a lot to read and absorb if we have to analyze it from scratch.

I sort of interpreted the original post as "I'm going to delete it all when this is solved".

Let me summarize what the program does:

There is an initial "source code" called prog.s that will have our fake "assembly" source code to "assemble" into our pseudo-machine code. This "machine code" is a set of integer values, one per line that hold an opcode, immediate bit, register values, etc (explained in the instructions)...

... I have the assembler working.

The VirtualMachine will take in the "machine code" generated from the assembler. It will load into a memory vector of a static size (256) starting at the TOP (position 0) of the vector, each instruction being in the next vector position (0,1,2,3,4....). A stack will build from the bottom of the vector.


The problem is that I have is the prog.s file I posted above, it is the same as the fact.s problem given in the instructions. This program simply takes a number from a file called prog.in and computes the factorial of that number, and outputs it into the .out file. I KNOW for a FACT that the prog.s or fact.s sample file is good and the logic works.
The problem is my virtual machine running it properly. I am (right now) going through ONE step at a time, literally pc=0, pc=1 and following the code through just to compute a factorial of 2 (lol) ... once it hits the recursion my mind goes crazy and I cannot figure out where I am and what is going on.

No matter what, the register 0, or r[0] is always 0 at the end of the program, no matter what number I insert to compute the factorial.

Thanks for any help given, I will be working on this all day, till I need to leave for school so any help is appreciated.

Edited 5 Years Ago by noobcoder: n/a

This article has been dead for over six months. Start a new discussion instead.