/vm.c
Last active
April 9, 2023 16:25
Revisions
-
DreamVB revised this gist
Jul 15, 2019 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,7 @@ 15/7/2019 + Added NEG, NOT , LT (Less Than),JF (Jump False) + Added simple IF example */ #include <stdio.h> -
DreamVB revised this gist
Jul 15, 2019 . 1 changed file with 85 additions and 8 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,20 +2,25 @@ Simple stack Virtual Machine Version 1.0 by DreamVB This is a simple example of how to code a simple VM in C At the moment this vm only supports a small amount of instruction I hope to add more as I learn more. This version has some hard coded example that you can test in the vm. Next version I plan to load the examples from files. If you like this code, or if you have some improvements I can make drop me a message below: dreamvb@outlook.com Happy-Coding 15/7/2019 + Added NEG, NOT , LT (Less Than),JF (Jump False) + Added simple example */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_PROG 65535 #define MAX_STACK 256 @@ -32,10 +37,16 @@ typedef enum { AND, OR, XOR, NEG, NOT, MOD, GSTORE, GLOAD, JMP, LT, GT, JT, JF, HLT, }OP_CODES; @@ -69,6 +80,41 @@ int Adder[] = { HLT }; int Neg[] = { PUSH, 124, NEG, PRTI, PUSH, -120, NEG, PRTI, HLT }; int Not[] = { PUSH, 1, NOT, PRTI, HLT }; int JumpTrue[] = { PUSH,8, PUSH, 6, LT, //True JF,10, PUSH,'T', PRTC, HLT, //False PUSH,'F', PRTC, HLT }; int Hello[] = { PUSH, 1234, @@ -155,8 +201,7 @@ void vm_execute(){ int r = 0; int l = 0; int r_idx = 0; //Loop while we still have code to execute while(pc < p_len){ //Read Instruction @@ -231,7 +276,39 @@ void vm_execute(){ l = STACK[sp--]; STACK[++sp] = (r ^ l); break; case NEG: r = -STACK[sp--]; STACK[++sp] = r; break; case NOT: r = !STACK[sp--]; STACK[++sp] = r; break; //Save the top of the stack into a global variable address. case LT: r = STACK[sp--]; l = STACK[sp--]; //test the two values on the stack if(l < r){ //Flag is true STACK[++sp] = 1; }else{ //Flag is false STACK[++sp] = 0; } break; //Jump False case JF: pc++; //Get the top of the stack r = STACK[sp--]; //Check for zero flag if(r == 0){ //Jump to code address. pc = pcode[pc]; } break; case GSTORE: pc++; //Get reg address. @@ -259,13 +336,13 @@ void vm_execute(){ } void vm_free(){ memset(pcode,0,sizeof(pcode)); } int main() { //Add code to VM vm_init(JumpTrue,sizeof(JumpTrue) / sizeof(int)); //Execute code vm_execute(); //Free the program code. -
DreamVB created this gist
Jul 14, 2019 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,275 @@ /* Simple stack Virtual Machine Version 1.0 by DreamVB This is a simple example of how to code a simple VM in C At the moment this vm only supports a small amount of instruction I hope to add more as I learn more. This version has some hard coded example that you can test in the vm. Next version I plan to load the examples from files. If you like this code, or if you have some improvements I can make drop me a message below: dreamvb@outlook.com Happy-Coding */ #include <stdio.h> #include <stdlib.h> #define MAX_PROG 65535 #define MAX_STACK 256 #define MAX_GLOBALS 8 typedef enum { PUSH = 0, PRTI, PRTC, ADD, SUB, MUL, DIV, AND, OR, XOR, MOD, GSTORE, GLOAD, JMP, HLT, }OP_CODES; //Program code to execute int pcode[MAX_PROG]; //Stack int STACK[MAX_STACK]; //Global variables pool int Globals[MAX_GLOBALS]; //Stack pointer int sp = -1; //Program counter int pc = 0; //Length of the current program to execute int p_len = 0; //Examples are shown below. int Adder[] = { PUSH, 150, PUSH, 150, ADD, PRTI, PUSH, 128, PUSH, 4, DIV, PRTI, HLT }; int Hello[] = { PUSH, 1234, PRTI, HLT }; int Logic[] = { PUSH, 5, PUSH, 14, XOR, PRTI, HLT }; int BasicVar[] = { PUSH, 150, PUSH, 120, ADD, GSTORE, 1, PUSH, 15, PRTI, GLOAD, 1, PRTI, HLT }; int Beep[] = { PUSH, 0x7, PRTC, HLT }; int Jump[] = { JMP, 4, PUSH, 20, PRTI, //Don't output the above PUSH, 141, PRTI, HLT }; int ModTest[] = { PUSH, 14, PUSH, 3, MOD, PRTI, HLT }; void vm_init(const int *code,int code_len){ int x = 0; p_len = code_len; //Load code into program code array. while(x < code_len){ pcode[x] = code[x]; //INC counter x++; } //Reset default variables values. x = 0; while(x < MAX_GLOBALS){ Globals[x] = 0; x++; } } void vm_execute(){ int op = 0; int r = 0; int l = 0; int r_idx = 0; int jp = 0; //Loop while we still have code to execute while(pc < p_len){ //Read Instruction op = pcode[pc]; //See what Instruction we are dealing with switch(op){ //Push a value to the top of the stack case PUSH: pc++; STACK[++sp] = pcode[pc]; break; //Print the top of the stack as an integer case PRTI: printf("%d\n",STACK[sp--]); break; //Print the top of the stack as a char case PRTC: printf("%c",STACK[sp--]); break; //Add the two top items on the stack and push back onto the stack. case ADD: r = STACK[sp--]; l = STACK[sp--]; STACK[++sp] = (r + l); break; //Subtract the two top items on the stack and push back onto the stack. case SUB: r = STACK[sp--]; l = STACK[sp--]; STACK[++sp] = (l - r); break; //Multiply the two top items on the stack and push back onto the stack. case MUL: r = STACK[sp--]; l = STACK[sp--]; STACK[++sp] = (r * l); break; //Divide the two top items on the stack and push back onto the stack. case DIV: r = STACK[sp--]; l = STACK[sp--]; //Check for division by zero error. if(r == 0){ printf("Division by zero"); //Set program counter to the end of the program code length. pc = p_len; }else{ STACK[++sp] = (l / r); } break; case MOD: r = STACK[sp--]; l = STACK[sp--]; STACK[++sp] = (l % r); break; case HLT: pc = p_len; break; case AND: r = STACK[sp--]; l = STACK[sp--]; STACK[++sp] = (r & l); break; case OR: r = STACK[sp--]; l = STACK[sp--]; STACK[++sp] = (r | l); break; case XOR: r = STACK[sp--]; l = STACK[sp--]; STACK[++sp] = (r ^ l); break; //Save the top of the stack into a global variable address. case GSTORE: pc++; //Get reg address. r_idx = pcode[pc]; //Get the tack value and put into reg Globals[r_idx] = STACK[sp--]; //Get what is on the stack. break; //Load a global variable and place on the stack case GLOAD: pc++; //Get reg index r_idx = pcode[pc]; STACK[++sp] = Globals[r_idx]; break; case JMP: pc++; //Jump to address pc = pcode[pc]; break; } //INC program counter pc++; } } void vm_free(){ free(pcode); } int main() { //Add code to VM vm_init(BasicVar,sizeof(BasicVar) / sizeof(int)); //Execute code vm_execute(); //Free the program code. vm_free(); //Return back to the operating system. return 0; }