C++ Virtual Machine
#include <windows.h> #include <iomanip> #include <cstdio> #include <fstream> #include <iostream> #include <string> #include <sstream> using namespace std; //Virtual Machine Global Variables int pc=0; int operand; int acc; int opcode; int Memory_data_register = 0; int command; int Programcounter=0; //Virtual Machine Functions int menu(); void VMstart(int); void about(); void load(); void display(); void documentation(); void execute(int); void run(); //Virtual Machine Constants; Instruction set const int CLR = 0; // acc = 0 const int LOAD = 1; // not implemented const int ADD = 2; // acc = acc + operand const int SUB = 3; // acc = acc - operand const int DIV = 4; const int MUL = 5; const int OUTPUT = 6; const int HALT = 0xFF; // HEX opcode to hlt cpu 244 const int JMP = 7; // pc = jmp's operand const int BNZ = 8; // Branch Not Zero operand . if (acc != 0) pc = operand const int STORES = 9; const int RUN = 10; const int QUIT = 11; //Our Ram with certain amounts of data; int RAM[10000]; string RAMdisplay[10000]; int main() { while(true) { command = menu(); if (command == 6){cout << "We are exiting virutal machine..."; return 0;} //Digit 6 represents quit. VMstart(command); } return 0; } void VMstart(int command){ switch(command) { case 1: //About about(); break; case 2: //Load data from text file load(); break; case 3: //Display data in our RAM display(); break; case 4: //Run run(); // Run will lead to execution of our opcode break; case 5: documentation(); break; default: cout << "Virtual Machine Exiting, Fatal error" << endl; exit(EXIT_FAILURE); system("pause"); break; } } void run () { if(Programcounter == 0){cout << "Error Cannot Run without loading data first\n"; system("pause"); return;} while(true) { opcode = RAM[pc]; //Grab the current opcode, starting from the beginning of our RAM. execute(opcode); if (opcode==HALT || opcode==QUIT) { cout << "Value of Accumulator is: " << acc << endl; if (Memory_data_register != 0){cout << "Value of memory is: " << Memory_data_register << endl;} cout << "We are halting or quitting the virtual machine....." << endl; system("pause"); return; } } } //Fetch Execute Cycle ALU void execute(int opcode) { switch (opcode) //Our opcode to determine what to do with each command inside of our RAM { case ADD: operand = RAM[++pc]; acc += operand; pc++; break; case SUB: operand = RAM[++pc]; acc -= operand; pc++; break; case MUL: operand = RAM[++pc]; acc *= operand; pc++; break; case BNZ: operand = RAM[++pc]; if ( acc != 0 ) pc = operand; else pc++; break; case CLR: acc = 0; pc++; break; case DIV: operand = RAM[++pc]; if (operand != 0) { acc /= operand; }else{ acc = 0; } pc++; break; case JMP: operand = RAM[++pc]; pc = operand; break; case OUTPUT: cout << "The content of the accumulator is: " << acc << endl; pc++; break; case STORES: Memory_data_register = acc; // pc++; break; case HALT: break; default: cout << "Unidentified word " << opcode << endl; } } //Open file and fetch each word seperated by a space and store it into our ram void load() { string filename,word; int i = 0; cout << "Enter file name in current directory: "; cin >> filename; ifstream input(filename.c_str()); if(!input.is_open()) { cout << "Your file was not found: " << endl; system("pause"); return; } cout << "File found:" << endl; system("pause"); //As long as we don't reach the end of the file continue to load data into our RAM while(!input.eof()) { input >> word; RAMdisplay[i]=word; if(word=="CLR") //Virtual machine commands that are allowed in your text file { RAM[i]=CLR; } else if(word=="ADD") { RAM[i]=ADD; } else if(word=="SUB") { RAM[i]=SUB; } else if(word=="DIV") { RAM[i]=DIV; } else if(word=="MUL") { RAM[i]=MUL; } else if(word=="OUT") { RAM[i]=OUTPUT; } else if(word=="HALT") { RAM[i]=HALT; } else if(word=="JMP") { RAM[i]=JMP; } else if(word=="BNZ") { RAM[i]=BNZ; } else if(word=="STORE") { RAM[i]=STORES; } else if(word=="RUN") { RAM[i]=RUN; } else if(word=="QUIT") { RAM[i]=QUIT; } else { stringstream number(word); number >> RAM[i]; if (word!="QUIT" && word!="RUN" && word!="BNZ" && word!="JMP" && word!="HALT" && word!="OUT" && word!="MUL" && word!="DIV" && word!="SUB" && word!="ADD" && word!="CLR"){ //A check in order to see if our virtual machine instructions are loadable. if(!number >> RAM[i]){ cout << "Error Loading data unidentified: " << word << endl; system("pause"); return; } } } i++; } Programcounter = i; cout << "Data Processed"<< endl; input.close(); system("pause"); } void display() { cout << "Displaying Data" << endl; if(Programcounter != 0){ for(int i=0; i<Programcounter; i++) { cout << RAMdisplay[i] << endl; } system("pause"); }else{cout << "Error cannot display data there is no data in our RAM" << endl; system("pause"); return;} } int menu() { int choice; system("CLS"); cout << "Simple CPU" << endl; cout << "1....About" << endl; cout << "2...Load Program" << endl; cout << "3...Display Program" << endl; cout << "4...Run Program" << endl; cout << "5...Documentation" << endl; cout << "6...QUIT" << endl; cout << "Choice:"; cin >> choice; cout << endl; return choice; } void about() { cout <<"Menu driven Calculator + Virtual Machine Version 1.0\n"; cout <<"(c) copyright 2015 Araf Shihab. All rights reserved.\n" << endl; system("pause"); } void documentation() { cout << "HELP" << endl << endl; cout << "1) IF The result of the vm is different from the result I did manually." << endl; cout << " --------" << "Make sure the commands that you type in your text file are proper commands" << endl << endl; cout << "Commands Available: CLR QUIT RUN BNZ JMP HALT OUT MUL DIV SUB ADD STORE" << endl; system("pause"); }
No comments:
Post a Comment