add: sqrt, neg instructions, fix: pushing register with value 0

This commit is contained in:
2024-01-20 19:36:41 +01:00
parent 0a8421fa4c
commit 2ab0d16928
4 changed files with 44 additions and 19 deletions

View File

@@ -7,7 +7,7 @@ OBJ = $(SRC:.c=.o)
NAME = pasm NAME = pasm
CC = gcc CC = gcc
CFLAGS = -Wall -Wextra -Wpedantic -Iinclude -s -Os -fno-ident -fno-asynchronous-unwind-tables CFLAGS = -Wall -Wextra -Wpedantic -Iinclude -s -Os -fno-ident -fno-asynchronous-unwind-tables
CLIBS = CLIBS = -lm
all: $(NAME) all: $(NAME)

View File

@@ -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 | | **sub** a1, a2 | Substract a2 from a1 | no |
| **mul** a1, a2 | Multiplies a2 with a1 | no | | **mul** a1, a2 | Multiplies a2 with a1 | no |
| **div** a1, a2 | Divides a2 from 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 | | **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 | | **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 | | **mov** a1, a2 | Moves the value stored in a2 in a1 | no |

View File

@@ -1,6 +1,7 @@
#include "instructions.h" #include "instructions.h"
#include "interpreter_states.h" #include "interpreter_states.h"
#include "api.h" #include "api.h"
#include <math.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@@ -25,7 +26,7 @@ bool check_args(s_arguments *args, int num_in_first, int num_args) {
return false; 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; state->last_check_args_code = ARG2_WRONG;
return false; 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) { int* get_reg(char* reg_char) {
switch (reg_char[1]) { switch (reg_char[1]) {
case '1' : case '1' :
return &state->registers->a1; return &state->registers->a1;
case '2' : case '2' :
return &state->registers->a2; return &state->registers->a2;
case '3' : case '3' :
return &state->registers->a3; return &state->registers->a3;
case '4' : case '4' :
return &state->registers->a4; return &state->registers->a4;
case '5' : case '5' :
return &state->registers->a5; return &state->registers->a5;
case '6' : case '6' :
return &state->registers->a6; return &state->registers->a6;
case '7' : case '7' :
return &state->registers->a7; return &state->registers->a7;
case '8' : case '8' :
return &state->registers->a8; return &state->registers->a8;
case '9' : case '9' :
return &state->registers->a9; return &state->registers->a9;
case 'a' : //eax case 'a' : //eax
return &state->registers->eax; return &state->registers->eax;
default : default :
return NULL; //should never happen return NULL; //should never happen
} }
} }
@@ -140,11 +141,11 @@ void jmp() {
return; return;
} }
} }
int line_off = atoi(state->args->arg1); int line_off = atoi(state->args->arg1);
if (line_off) { if (line_off) {
state->curr_line += line_off; state->curr_line += line_off;
return; return;
} }
state->last_jmp_code = 1; state->last_jmp_code = 1;
return; return;
@@ -189,6 +190,23 @@ void add() {
*get_reg(state->args->arg1) += get_value(state->args->arg2); *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() { void mul() {
if (!check_args(state->args, 0, 2)) { if (!check_args(state->args, 0, 2)) {
return; return;
@@ -230,7 +248,7 @@ void push() {
} }
int value = get_value(state->args->arg1); int value = get_value(state->args->arg1);
if (value == 0) { if (value == 0 && !is_reg(state->args->arg1)) {
if (state->args->arg1[0] == '\\') { if (state->args->arg1[0] == '\\') {
switch (state->args->arg1[1]) { switch (state->args->arg1[1]) {
case 'n': case 'n':

View File

@@ -11,6 +11,7 @@ typedef struct command_s {
bool is_reg(char* arg); bool is_reg(char* arg);
bool check_args(s_arguments *args, int num_in_first, int num_args); bool check_args(s_arguments *args, int num_in_first, int num_args);
int* get_reg(char* arg); int* get_reg(char* arg);
int get_value(char* arg);
void add(); void add();
void sub(); void sub();
@@ -29,6 +30,8 @@ void ret();
void pop(); void pop();
void push(); void push();
void call(); void call();
void neg();
void _sqrt();
void _and(); void _and();
void _xor(); void _xor();
void end(); void end();
@@ -51,6 +54,8 @@ static const command_t command_map[] = {
{.command = "pop", .fptr = pop}, {.command = "pop", .fptr = pop},
{.command = "push", .fptr = push}, {.command = "push", .fptr = push},
{.command = "call", .fptr = call}, {.command = "call", .fptr = call},
{.command = "sqrt", .fptr = _sqrt},
{.command = "neg", .fptr = neg},
{.command = "and", .fptr = _and}, {.command = "and", .fptr = _and},
{.command = "xor", .fptr = _xor}, {.command = "xor", .fptr = _xor},
{.command = "end", .fptr = end}, {.command = "end", .fptr = end},