From 2ab0d16928e0098f82e289936a92f66d96a02ae4 Mon Sep 17 00:00:00 2001 From: ALittlePatate Date: Sat, 20 Jan 2024 19:36:41 +0100 Subject: [PATCH] add: sqrt, neg instructions, fix: pushing register with value 0 --- Makefile | 2 +- docs/documentation.md | 2 ++ src/instructions.c | 54 ++++++++++++++++++++++++++++--------------- src/instructions.h | 5 ++++ 4 files changed, 44 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 4e10f4e..a4bb539 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ OBJ = $(SRC:.c=.o) NAME = pasm CC = gcc CFLAGS = -Wall -Wextra -Wpedantic -Iinclude -s -Os -fno-ident -fno-asynchronous-unwind-tables -CLIBS = +CLIBS = -lm all: $(NAME) diff --git a/docs/documentation.md b/docs/documentation.md index 25584f6..3ac5e51 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -71,6 +71,8 @@ The syntax is very close to x86 Intel Assembly. Here is a list of the operands a | **sub** a1, a2 | Substract a2 from a1 | no | | **mul** a1, a2 | Multiplies a2 with a1 | no | | **div** a1, a2 | Divides a2 from a1 | no | +| **sqrt** a1 | computes sqrt(a1) | no | +| **neg** a1 | a1 = -a1 | no | | **and** a1, a2 | Performs a bitwise AND between a1 and a2. Stores the result in eax. | yes | | **xor** a1, a2 | Performs a XOR opration between a1 and a2. Stores the result in eax.| yes | | **mov** a1, a2 | Moves the value stored in a2 in a1 | no | diff --git a/src/instructions.c b/src/instructions.c index 00268b5..70f11b7 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -1,6 +1,7 @@ #include "instructions.h" #include "interpreter_states.h" #include "api.h" +#include #include #include @@ -25,7 +26,7 @@ bool check_args(s_arguments *args, int num_in_first, int num_args) { return false; } - if ((!is_num(args->arg2) && !is_reg(args->arg2))) { + if ((!is_num(args->arg2) && !is_reg(args->arg2)) && num_args == 2) { state->last_check_args_code = ARG2_WRONG; return false; } @@ -35,27 +36,27 @@ bool check_args(s_arguments *args, int num_in_first, int num_args) { int* get_reg(char* reg_char) { switch (reg_char[1]) { case '1' : - return &state->registers->a1; + return &state->registers->a1; case '2' : - return &state->registers->a2; + return &state->registers->a2; case '3' : - return &state->registers->a3; + return &state->registers->a3; case '4' : - return &state->registers->a4; + return &state->registers->a4; case '5' : - return &state->registers->a5; + return &state->registers->a5; case '6' : - return &state->registers->a6; + return &state->registers->a6; case '7' : - return &state->registers->a7; + return &state->registers->a7; case '8' : - return &state->registers->a8; + return &state->registers->a8; case '9' : - return &state->registers->a9; + return &state->registers->a9; case 'a' : //eax - return &state->registers->eax; + return &state->registers->eax; default : - return NULL; //should never happen + return NULL; //should never happen } } @@ -140,11 +141,11 @@ void jmp() { return; } } - int line_off = atoi(state->args->arg1); - if (line_off) { - state->curr_line += line_off; - return; - } + int line_off = atoi(state->args->arg1); + if (line_off) { + state->curr_line += line_off; + return; + } state->last_jmp_code = 1; return; @@ -189,6 +190,23 @@ void add() { *get_reg(state->args->arg1) += get_value(state->args->arg2); } + +void _sqrt() { + if (!check_args(state->args, 0, 1)) { + return; + } + + *get_reg(state->args->arg1) = sqrt(get_value(state->args->arg1)); +} + +void neg() { + if (!check_args(state->args, 0, 1)) { + return; + } + + *get_reg(state->args->arg1) = -get_value(state->args->arg1); +} + void mul() { if (!check_args(state->args, 0, 2)) { return; @@ -230,7 +248,7 @@ void push() { } int value = get_value(state->args->arg1); - if (value == 0) { + if (value == 0 && !is_reg(state->args->arg1)) { if (state->args->arg1[0] == '\\') { switch (state->args->arg1[1]) { case 'n': diff --git a/src/instructions.h b/src/instructions.h index fa6debd..52f9db8 100644 --- a/src/instructions.h +++ b/src/instructions.h @@ -11,6 +11,7 @@ typedef struct command_s { bool is_reg(char* arg); bool check_args(s_arguments *args, int num_in_first, int num_args); int* get_reg(char* arg); +int get_value(char* arg); void add(); void sub(); @@ -29,6 +30,8 @@ void ret(); void pop(); void push(); void call(); +void neg(); +void _sqrt(); void _and(); void _xor(); void end(); @@ -51,6 +54,8 @@ static const command_t command_map[] = { {.command = "pop", .fptr = pop}, {.command = "push", .fptr = push}, {.command = "call", .fptr = call}, + {.command = "sqrt", .fptr = _sqrt}, + {.command = "neg", .fptr = neg}, {.command = "and", .fptr = _and}, {.command = "xor", .fptr = _xor}, {.command = "end", .fptr = end},