From fc56815f74f4ae94fb03418917041047c425c203 Mon Sep 17 00:00:00 2001 From: ALittlePatate Date: Sat, 5 Aug 2023 19:49:39 +0200 Subject: [PATCH] add return stack now we can jump where we want --- docs/documentation.md | 18 +----------------- src/instructions.c | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/documentation.md b/docs/documentation.md index 6dcb5c3..4fce0fc 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -95,22 +95,6 @@ Note that return can be used in a conditional jump like so : cmp a1, 5 je return ; note it's return and not ret when used like this ``` -Due to current limitations, you can't jump to more than one function and return to the right place. Example : -```asm -bar: -add a1, 2 -ret - -foo: -add a1, 3 -jmp bar -ret - -main: -jmp foo -; more code -``` -Here `foo` will never return to the main function and will instead return to `ret`. TOFIX !! ### Calling APIs APIs can be added in the [api.c](https://github.com/ALittlePatate/pasm/blob/main/src/api.c) and [api.h](https://github.com/ALittlePatate/pasm/blob/main/src/api.h) files. @@ -124,7 +108,7 @@ Here is a list of all the errors you can encounter and how to fix them : * `wrong number of arguments on line X` : you have more or less arguments needed for an operand, see [table](#syntax). * `arg1/arg2 is invalid on line X` : the operand used can't work with the type of argument provided (register/number/char) * `X is not a valid label/api` : you tried to jump (`jmp`) or `call` an undefined label or non-existing API. Check [Scripts structure](scripts-structure). -* `stack overflow on line X` : you pushed to many times without poping. +* `stack overflow on line X` : you pushed to many times without poping or you reached the recursion depth limit. * `stack underflow on line X` : you poped to many times without pushing. ## Running a script diff --git a/src/instructions.c b/src/instructions.c index 97143d9..94470e5 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -5,6 +5,8 @@ #include #include +int RET_STACK[STACK_SIZE] = {-1*STACK_SIZE}; +int RET_STACK_IDX = 0; bool is_reg(char* arg) { return (strcmp(arg, "eax") == 0) || (((arg[0] == 'a' && '0' <= arg[1] <= '9')) && strlen(arg) == 2); } @@ -93,17 +95,33 @@ void cmp() { return; } -int line_should_ret = -1; +int CheckRetStack() { + if (RET_STACK_IDX > STACK_SIZE) { + last_stack_code = OVERFLOW; + return 0; + } + if (RET_STACK_IDX < 0) { + last_stack_code = UNDERFLOW; + return 0; + } + + return 1; +} + void ret() { - if (line_should_ret == -1) { + if (!CheckRetStack()) return; + + if (RET_STACK[RET_STACK_IDX] == -1) { exit_code = 1; return; } - fseek(fptr, line_should_ret, SEEK_SET); + fseek(fptr, RET_STACK[RET_STACK_IDX--], SEEK_SET); } void jmp() { + if (!CheckRetStack()) return; + if (strcmp(args->arg1, "return") == 0) { ret(); return; @@ -113,7 +131,7 @@ void jmp() { for (int i = 0; i < MAX_LABEL; i++) { if (labels[i] == NULL) break; if (strcmp(args->arg1, labels[i]) == 0) { - line_should_ret = (int)char_read; + RET_STACK[RET_STACK_IDX++] = (int)char_read; fseek(fptr, labels_lines[i], SEEK_SET); char_read = labels_lines[i]; return;