diff --git a/SDA.c b/SDA.c index ff50bd2..d54a9c9 100644 --- a/SDA.c +++ b/SDA.c @@ -6,21 +6,22 @@ #include struct sda { - int *size; unsigned int *sda; + int size; }; -unsigned int getSDA(int i, struct sda s) { - return s.sda[i]; +int getSDA(unsigned int offset, struct sda *sda) { + return sda->sda[offset]; } -void setSDA(int point, int val, struct sda s) { - s.sda[point] = val; +void setSDA(unsigned int offset, int value, struct sda *sda) { + sda->sda[offset] = value; } -void printSDA(struct sda s) { - for (int i = 0; i < *s.size; i++) { - printf("%i\n", getSDA(i, s)); +void printSDA(struct sda *sda) { + printf("SDA:\n"); + for (int i = 0; i < sda->size; ++i) { + printf("[%d] = %d\n", i, sda->sda[i]); } } diff --git a/codeReader.c b/codeReader.c index d94d25b..858813e 100644 --- a/codeReader.c +++ b/codeReader.c @@ -6,7 +6,7 @@ #include #include "program.c" -unsigned int fromFile(char *path, struct program program) { +unsigned int fromFile(char *path, struct program *program) { unsigned int countInstructions; unsigned int staticVars; FILE *fptr; diff --git a/njvm.c b/njvm.c index 5d77770..11b4251 100644 --- a/njvm.c +++ b/njvm.c @@ -7,15 +7,10 @@ #include "codeReader.c" #include "SDA.c" -// Stack -struct stack stack; -#define SIZE 1000 - // Program -struct program program; +struct program *program; // SDA -struct sda sda; unsigned fp; void version(void) { @@ -26,104 +21,129 @@ void help(void) { printf("Usage: ./njvm [options] \n\t--debug\tstart virtual machine in debug mode\n\t--version\tshow version and exit\n\t--help\t\tshow this help and exit\n"); } -void execute(struct program program) { - int i; +void execute(struct program *program, struct sda *sda) { + struct stack stack; + stack.size = 1000; + stack.currentFrame = 0; + + for (int i = 0; i < stack.size; ++i) { + struct stackFrame *frame = malloc(sizeof(struct stackFrame)); + frame->fp = malloc(sizeof(unsigned int) * stack.size); + frame->sp = malloc(sizeof(unsigned int) * stack.size); + frame->bp = NULL; + stack.frames[i] = frame; + } + + struct stackFrame *currentFrame = NULL; + unsigned int tmp; int intInput; - unsigned int temp; char charInput; - for (i = 0; i < *program.size; ++i) { - switch (program.program[i] >> 24) { + + for (int i = 0; i < program->size; ++i) { + unsigned int instruction = program->program[i]; + switch (instruction >> 24) { case HALT: goto end; case PUSHC: - push(stack, SIGN_EXTEND(IMMEDIATE(program.program[i]))); + push(&stack, SIGN_EXTEND(IMMEDIATE(instruction))); break; case ADD: - push(stack, pop(stack) + pop(stack)); + push(&stack, pop(&stack) + pop(&stack)); break; case SUB: - temp = pop(stack); - push(stack, pop(stack) - temp); + tmp = pop(&stack); + push(&stack, pop(&stack) - tmp); break; case MUL: - push(stack, pop(stack) * pop(stack)); + push(&stack, pop(&stack) * pop(&stack)); break; case DIV: - temp = pop(stack); - push(stack, pop(stack) / temp); + tmp = pop(&stack); + push(&stack, pop(&stack) / tmp); break; case MOD: - temp = pop(stack); - push(stack, pop(stack) % temp); + tmp = pop(&stack); + push(&stack, pop(&stack) % tmp); break; case RDINT: scanf("%i", &intInput); - push(stack, intInput); + push(&stack, intInput); break; case WRINT: - printf("%i", pop(stack)); + printf("%i", pop(&stack)); break; case RDCHR: scanf("%c", &charInput); - push(stack, charInput); + push(&stack, charInput); break; case WRCHR: - printf("%c", pop(stack)); + printf("%c", pop(&stack)); break; case PUSHG: - push(stack, getSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), sda)); + currentFrame = stack.frames[stack.currentFrame]; + currentFrame->bp = currentFrame->sp; + + *currentFrame->sp++ = getSDA(SIGN_EXTEND(IMMEDIATE(instruction)), sda); break; case POPG: - setSDA(SIGN_EXTEND(IMMEDIATE(program.program[i])), pop(stack), sda); + currentFrame = stack.frames[stack.currentFrame]; + currentFrame->bp = currentFrame->sp; + + setSDA(SIGN_EXTEND(IMMEDIATE(instruction)), pop(&stack), sda); break; case ASF: - push(stack, *stack.current); - fp = *stack.current; - *stack.current = *stack.current + SIGN_EXTEND(IMMEDIATE(program.program[i])); + currentFrame = stack.frames[stack.currentFrame]; + push(&stack, *currentFrame->sp); + *currentFrame->sp = stack.currentFrame; + currentFrame->bp = currentFrame->sp; + + stack.currentFrame += SIGN_EXTEND(IMMEDIATE(instruction)); break; case RSF: - *stack.current = fp; - fp = pop(stack); + stack.currentFrame = pop(&stack); + currentFrame = stack.frames[stack.currentFrame]; + currentFrame->bp = NULL; + break; case PUSHL: - stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))] = pop(stack); + currentFrame = stack.frames[stack.currentFrame]; + push(&stack, currentFrame->fp[SIGN_EXTEND(IMMEDIATE(instruction))]); break; case POPL: - push(&stack, stack.stack[fp + SIGN_EXTEND(IMMEDIATE(program.program[i]))]); + currentFrame = stack.frames[stack.currentFrame]; + currentFrame->fp[SIGN_EXTEND(IMMEDIATE(instruction))] = pop(&stack); break; } } + end: return; } +// run prog2.bin void tests(void) { - printf("Runnig debug mode\n"); - int temp = fromFile("./prog2.bin", program); - int sizeSDA = temp; - unsigned int s[sizeSDA]; - sda.size = &temp; - sda.sda = s; - printProgram(program); - execute(program); - printSDA(sda); + printf("Test started\n"); + struct sda *sda = malloc(sizeof(struct sda)); + unsigned int s[1000]; + sda->size = 1000; + sda->sda = s; + fromFile("prog2.bin", program); + execute(program, (struct sda *) &sda); + printf("Test finished\n"); } int main(int argc, char *argv[]) { // Initialize the Stack + struct stack stack; int size = SIZE; - int current = 0; - unsigned int s[SIZE]; - stack.size = &size; - stack.current = ¤t; - stack.stack = s; + stack.size = size; + stack.currentFrame = 0; // Initialize ProgrammSpeicher - int psize = 1000; - int saveProgram = 0; + int psize = SIZE; unsigned int p[1000]; - program.size = &psize; - program.program = p; - program.saveProgram = &saveProgram; + program = malloc(sizeof(struct program)); + program->size = psize; + program->program = p; // Initialize runtime variables int debug = 0; @@ -159,15 +179,17 @@ int main(int argc, char *argv[]) { */ if (run) { printf("Ninja Virtual Machine started\n"); + struct sda *sda = malloc(sizeof(struct sda)); unsigned int s[sizeSDA]; - sda.size = &sizeSDA; - sda.sda = s; + sda->size = sizeSDA; + sda->sda = s; printProgram(program); - execute(program); + execute(program, (struct sda *) &sda); if (debug == 1) printSDA(sda); printf("Ninja Virtual Machine stopped\n"); } else { printf("Error: no code file specified\n"); return 1; } + return 0; } diff --git a/program.c b/program.c index 02bed77..5b48b41 100644 --- a/program.c +++ b/program.c @@ -9,23 +9,21 @@ #include struct program { - int *size; unsigned int *program; - int *saveProgram; + int size; }; -void copyToProgram(const unsigned int codeToCopy[], int size, struct program program) { +void copyToProgram(const unsigned int codeToCopy[], int size, struct program *program) { for (int i = 0; i < size; ++i) { - program.program[i] = codeToCopy[i]; + program->program[i] = codeToCopy[i]; } - *program.size = size; - *program.saveProgram = 1; + program->size = size; } -void printProgram(struct program program) { +void printProgram(struct program *program) { char c[10]; - for (int i = 0; i < *program.size; i++) { - switch (program.program[i] >> 24) { + for (int i = 0; i < program->size; i++) { + switch (program->program[i] >> 24) { case PUSHC: strcpy(c, "pushc"); break; @@ -81,7 +79,7 @@ void printProgram(struct program program) { strcpy(c, "ERROR"); break; } - IMMEDIATE(program.program[i]) ? printf("%03i:\t%s\t%i\n", i, c, SIGN_EXTEND(IMMEDIATE(program.program[i]))) : printf( + IMMEDIATE(program->program[i]) ? printf("%03i:\t%s\t%i\n", i, c, SIGN_EXTEND(IMMEDIATE(program->program[i]))) : printf( "%03i:\t%s\n", i, c); } } diff --git a/programs/prog-test-1.asm b/programs/prog-test-1.asm new file mode 100644 index 0000000..2afc7d5 --- /dev/null +++ b/programs/prog-test-1.asm @@ -0,0 +1,11 @@ +pushc 3 +pushc 4 +add +pushc 10 +pushc 6 +sub +mul +wrint +pushc 10 +wrchr +halt diff --git a/programs/prog-test-1.bin b/programs/prog-test-1.bin new file mode 100644 index 0000000..fb7669e Binary files /dev/null and b/programs/prog-test-1.bin differ diff --git a/programs/prog-test-2.asm b/programs/prog-test-2.asm new file mode 100644 index 0000000..53221e3 --- /dev/null +++ b/programs/prog-test-2.asm @@ -0,0 +1,9 @@ + pushc -2 + rdint + mul + pushc 3 + add + wrint + pushc '\n' + wrchr + halt diff --git a/programs/prog-test-2.bin b/programs/prog-test-2.bin new file mode 100644 index 0000000..2cced0f Binary files /dev/null and b/programs/prog-test-2.bin differ diff --git a/programs/prog-test-3.asm b/programs/prog-test-3.asm new file mode 100644 index 0000000..52ea594 --- /dev/null +++ b/programs/prog-test-3.asm @@ -0,0 +1,5 @@ + rdchr + wrint + pushc '\n' + wrchr + halt diff --git a/programs/prog-test-3.bin b/programs/prog-test-3.bin new file mode 100644 index 0000000..cf2d641 Binary files /dev/null and b/programs/prog-test-3.bin differ diff --git a/prog1.asm b/programs/prog1.asm similarity index 100% rename from prog1.asm rename to programs/prog1.asm diff --git a/prog1.bin b/programs/prog1.bin similarity index 100% rename from prog1.bin rename to programs/prog1.bin diff --git a/prog2.asm b/programs/prog2.asm similarity index 100% rename from prog2.asm rename to programs/prog2.asm diff --git a/prog2.bin b/programs/prog2.bin similarity index 100% rename from prog2.bin rename to programs/prog2.bin diff --git a/stack.c b/stack.c index 8a38d26..f84d3ab 100755 --- a/stack.c +++ b/stack.c @@ -3,38 +3,39 @@ // #ifndef STACK #define STACK +#define SIZE 1000 + #include #include -struct stack { - int* size; - int* current; - unsigned int *stack; +struct stackFrame { + unsigned int *fp; // Frame pointer + unsigned int *sp; // Stack pointer + unsigned int *bp; // Base pointer }; -void printStack(struct stack stack) { - printf("Stack\nSize:\t\t%i\nCurrent:\t%i\n", *stack.size, *stack.current); - for (int i = 0; i < *stack.size; ++i) { - printf("|%i|\n", stack.stack[i]); +struct stack { + int size; + int currentFrame; + struct stackFrame *frames[SIZE]; +}; + +void printStack(struct stack *stack) { + printf("Stack:\n"); + for (int i = 0; i < stack->size; ++i) { + printf("[%d] = %d\n", i, stack->frames[stack->currentFrame]->sp[i]); } } -void push(struct stack s, unsigned int value) { - if (*s.current >= *s.size) { - printf("Stack Overflow\n"); - exit(EXIT_FAILURE); - } - s.stack[*s.current] = value; - *s.current=*s.current + 1; +void push(struct stack *stack, int value) { + struct stackFrame *currentFrame = stack->frames[stack->currentFrame]; + *currentFrame->sp++ = value; } -unsigned int pop(struct stack s) { - if (*s.current == 0) { - printf("Stack Underflow\n"); - exit(EXIT_FAILURE); - } - *s.current = *s.current -1; - return s.stack[*s.current]; +int pop(struct stack *stack) { + struct stackFrame *currentFrame = stack->frames[stack->currentFrame]; + return *--currentFrame->sp; } + #endif