diff --git a/consts.c b/consts.c index 4a9d776..fe01ea4 100644 --- a/consts.c +++ b/consts.c @@ -1,6 +1,6 @@ #ifndef CONSTS #define CONSTS -#define VERSION 3 +#define VERSION 4 #endif /* ifndef CONSTS #define CONSTS diff --git a/instruktion.c b/instruktion.c index 7c30044..015d2c4 100644 --- a/instruktion.c +++ b/instruktion.c @@ -31,5 +31,8 @@ #define JMP 23 #define BRF 24 #define BRT 25 +#define CALL 26 +#define RET 27 +#define DROP 28 #endif /* ifndef INSREUKTION */ diff --git a/njvm.c b/njvm.c index 4daa57c..f642d31 100644 --- a/njvm.c +++ b/njvm.c @@ -11,7 +11,7 @@ struct program *program; // SDA -unsigned fp; +int fp; int debug = 0; void version(void) { @@ -26,16 +26,28 @@ void execute(struct program *program, struct sda *sda) { struct stack stack; stack.size = 1000; stack.currentFrame = 0; + struct stack callStack; + callStack.size = 1000; + callStack.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->fp = malloc(sizeof(int) * stack.size); + frame->sp = malloc(sizeof(int) * stack.size); frame->bp = NULL; stack.frames[i] = frame; } + for (int i = 0; i < callStack.size; ++i) { + struct stackFrame *frame = malloc(sizeof(struct stackFrame)); + frame->fp = malloc(sizeof(int) * stack.size); + frame->sp = malloc(sizeof(int) * stack.size); + frame->bp = NULL; + callStack.frames[i] = frame; + } + struct stackFrame *currentFrame = NULL; + //struct stackFrame *currentCallFrame = NULL; unsigned int tmp; int intInput; char charInput; @@ -130,7 +142,9 @@ void execute(struct program *program, struct sda *sda) { case PUSHL: if (debug == 1) printf("PUSHL %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); currentFrame = stack.frames[stack.currentFrame]; - push(&stack, currentFrame->fp[SIGN_EXTEND(IMMEDIATE(instruction))]); + currentFrame->bp = currentFrame->sp; + int x = SIGN_EXTEND(IMMEDIATE(instruction)); + push(&stack, currentFrame->fp[x]); break; case POPL: if (debug == 1) printf("POPL %d\n", SIGN_EXTEND(IMMEDIATE(instruction))); @@ -224,6 +238,31 @@ void execute(struct program *program, struct sda *sda) { i = j; } break; + case CALL: + tmp = SIGN_EXTEND(IMMEDIATE(program->program[i])); + if (j-- >= program->size) { + printf("Error: Call out of program memory\n"); + goto end; + } + push(&callStack, i + 1); + i = tmp; + break; + case RET: + if (debug == 1) printf("RET\n"); + tmp = pop(&callStack); + if (tmp-- >= program->size) { + printf("Error: Return out of program memory\n"); + goto end; + } + i = tmp; + break; + case DROP: + tmp = SIGN_EXTEND(IMMEDIATE(instruction)); + if (debug == 1) printf("DROP %d\n", tmp); + for (int b = 0; b < tmp; ++b) { + pop(&stack); + } + break; } } diff --git a/program.c b/program.c index b2a8dd9..e7b35ea 100644 --- a/program.c +++ b/program.c @@ -99,6 +99,15 @@ void printProgram(struct program *program) { case BRT: strcpy(c,"brt"); break; + case CALL: + strcpy(c,"call"); + break; + case RET: + strcpy(c,"ret"); + break; + case DROP: + strcpy(c,"drop"); + break; default: strcpy(c, "ERROR"); break; diff --git a/programs/prog5.asm b/programs/prog5.asm new file mode 100644 index 0000000..6d40f30 --- /dev/null +++ b/programs/prog5.asm @@ -0,0 +1,35 @@ +// +// prog01.asm -- call/ret without args, and without ret value +// + + asf 3 + pushc 11 + wrint + pushc '\n' + wrchr + call proc + pushc 44 + wrint + pushc '\n' + wrchr + rsf + halt + +proc: + asf 2 + pushc 22 + wrint + pushc '\n' + wrchr + call proctwo + rsf + ret + +proctwo: + asf 2 + pushc 33 + wrint + pushc '\n' + wrchr + rsf + ret diff --git a/programs/prog5.bin b/programs/prog5.bin new file mode 100644 index 0000000..e315107 Binary files /dev/null and b/programs/prog5.bin differ diff --git a/programs/prog6.asm b/programs/prog6.asm new file mode 100644 index 0000000..eb3b037 --- /dev/null +++ b/programs/prog6.asm @@ -0,0 +1,28 @@ +// +// prog02.asm -- call/ret with args, but without ret value +// + + asf 3 + pushc 11 + pushc 33 + call proc + drop 2 + rsf + halt + +proc: + asf 2 + pushl -4 + wrint + pushc '\n' + wrchr + pushc 22 + wrint + pushc '\n' + wrchr + pushl -3 + wrint + pushc '\n' + wrchr + rsf + ret diff --git a/programs/prog6.bin b/programs/prog6.bin new file mode 100644 index 0000000..d7abab7 Binary files /dev/null and b/programs/prog6.bin differ diff --git a/stack.c b/stack.c index 4eb2c26..88b1904 100755 --- a/stack.c +++ b/stack.c @@ -10,9 +10,9 @@ #include struct stackFrame { - unsigned int *fp; // Frame pointer - unsigned int *sp; // Stack pointer - unsigned int *bp; // Base pointer + int *fp; // Frame pointer + int *sp; // Stack pointer + int *bp; // Base pointer }; struct stack { @@ -28,14 +28,16 @@ void printStack(struct stack *stack) { } } -void push(struct stack *stack, int value) { +void push(struct stack *stack, unsigned int value) { struct stackFrame *currentFrame = stack->frames[stack->currentFrame]; - *currentFrame->sp++ = value; + *(currentFrame->sp) = value; + currentFrame->sp++; } int pop(struct stack *stack) { struct stackFrame *currentFrame = stack->frames[stack->currentFrame]; - return *--currentFrame->sp; + currentFrame->sp--; + return *(currentFrame->sp); } int peek(struct stack *stack, int steps) { // peek is pop without removing the value