From 8d2cd435d064b30bb25e786deeb9fba4adee677c Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Thu, 6 Jul 2023 14:30:40 +0900 Subject: [PATCH] Implement the int instruction --- .gitignore | 1 + Makefile | 3 +++ shell.nix | 1 + src/instructions.c | 2 +- src/instructions.h | 1 + src/instructions/memory.c | 38 ++++++++++++++++++++++++++++++++++++++ src/interpretor.c | 24 ++++++++++++++++-------- src/interpretor.h | 9 +++++++++ 8 files changed, 70 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index fce30e4..87b10e4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ setuptools ._setuptools *.o dasm +.vgcore* diff --git a/Makefile b/Makefile index 6131866..79a93d6 100644 --- a/Makefile +++ b/Makefile @@ -23,3 +23,6 @@ fclean: clean $(RM) $(NAME) re: fclean all + +dbg: $(CFLAGS += -g) +dbg: re diff --git a/shell.nix b/shell.nix index 135cee1..b29bfb9 100644 --- a/shell.nix +++ b/shell.nix @@ -3,5 +3,6 @@ pkgs.mkShell { packages = with pkgs; [ gcc gnumake + valgrind ]; } diff --git a/src/instructions.c b/src/instructions.c index 78b4df8..b3ebd38 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -210,7 +210,7 @@ const instruction_t instructions[] = { {.opcode = 0xCA, .extended = -1, .name = "retf", .mode = {IMM16, END}, .exec = NULL}, {.opcode = 0xCB, .extended = -1, .name = "retf", .mode = {END}, .exec = NULL}, {.opcode = 0xCC, .extended = -1, .name = "int3", .mode = {END}, .exec = NULL}, - {.opcode = 0xCD, .extended = -1, .name = "int", .mode = {IMM8, END}, .exec = NULL}, + {.opcode = 0xCD, .extended = -1, .name = "int", .mode = {IMM8, END}, .exec = &int_inst}, {.opcode = 0xCE, .extended = -1, .name = "into", .mode = {END}, .exec = NULL}, {.opcode = 0xCF, .extended = -1, .name = "iret", .mode = {END}, .exec = NULL}, {.opcode = 0xD0, .extended = 7, .name = "EXTENDED", .mode = {END}, .exec = NULL}, diff --git a/src/instructions.h b/src/instructions.h index 0725a62..d413c04 100644 --- a/src/instructions.h +++ b/src/instructions.h @@ -4,3 +4,4 @@ #include "interpretor.h" void mov(const instruction_t *self, state_t *state); +void int_inst(const instruction_t *self, state_t *state); diff --git a/src/instructions/memory.c b/src/instructions/memory.c index abd14ca..db442b5 100644 --- a/src/instructions/memory.c +++ b/src/instructions/memory.c @@ -1,8 +1,11 @@ #include #include #include +#include +#include #include "../dasm.h" #include "../interpretor.h" +#include "sys/types.h" void mov(const instruction_t *self, state_t *state) { @@ -14,3 +17,38 @@ void mov(const instruction_t *self, state_t *state) else *(uint8_t *)from = *(uint8_t *)to; } + +void int_inst(const instruction_t *self, state_t *state) +{ + // I have no clue what the use of type is. + // uint8_t type = *(uint8_t *)get_operand(self, 0, state); + syscall_t *syscall = (syscall_t *)(state->memory + state->bx); + uint8_t *args = state->memory + state->bx + sizeof(*syscall); + + (void)self; + + switch (syscall->type) { + case 0x1: + printf("\n", *args); + exit(state->bx); + case 0x2: + printf(" %d>\n", 0); + printf("Not implemented\n"); + break; + case 0x4: { + uint16_t fd = *(uint16_t *)args; + uint16_t len = *((uint16_t *)args + 1); + // the 2 args (a number is skiped.) + uint16_t addr = *((uint16_t *)args + 3); + printf("memory[addr], len); + printf(" => %d>\n", ret); + state->ax = 0; + break; + } + default: + printf("Unimplemented syscall %02X\n", syscall->type); + break; + } +} diff --git a/src/interpretor.c b/src/interpretor.c index f983c51..f386f7c 100644 --- a/src/interpretor.c +++ b/src/interpretor.c @@ -1,4 +1,5 @@ #include +#include #include #include #include "dasm.h" @@ -54,21 +55,21 @@ void *get_rm_operand(state_t *state, unsigned *imm_idx, bool is16bit) switch (rm) { case 0x00: - return state->binary + state->bx + state->si + disp; + return state->memory + state->bx + state->si + disp; case 0x01: - return state->binary + state->bx + state->di + disp; + return state->memory + state->bx + state->di + disp; case 0x02: - return state->binary + state->bp + state->si + disp; + return state->memory + state->bp + state->si + disp; case 0x03: - return state->binary + state->bp + state->di + disp; + return state->memory + state->bp + state->di + disp; case 0x04: - return state->binary + state->si + disp; + return state->memory + state->si + disp; case 0x05: - return state->binary + state->di + disp; + return state->memory + state->di + disp; case 0x06: - return state->binary + state->bp + disp; + return state->memory + state->bp + disp; case 0x07: - return state->binary + state->bx + disp; + return state->memory + state->bx + disp; } return NULL; } @@ -169,19 +170,26 @@ int interpret(u_int8_t *binary, unsigned long size) { state_t *state = calloc(sizeof(*state), 1); int header_size = 0; + int dsize= 0; + + state->sp = 0xFFDC; if (binary[0] == 0xEB && binary[1] == 0x0E) { header_size = 16; size = binary[2] | (binary[3] << 8); + dsize = binary[4] | (binary[5] << 8); } else if (binary[0] == 0x01 && binary[1] == 0x03) { header_size = binary[4]; size = binary[8] | (binary[9] << 8) | (binary[10] << 16) | (binary[11] << 24); + dsize = binary[12] | (binary[13] << 8) | (binary[14] << 16) | (binary[15] << 24); } binary += header_size; state->binary = binary; state->binary_size = size; + memcpy(state->memory, binary + size, dsize); + printf(" AX BX CX DX SP BP SI DI FLAGS IP\n"); while (state->pc < size) { instruction_t inst = parse_inst(binary, size - state->pc); diff --git a/src/interpretor.h b/src/interpretor.h index e7b3ee3..5d6ef58 100644 --- a/src/interpretor.h +++ b/src/interpretor.h @@ -3,6 +3,8 @@ #include #include +#define MEMORY_SIZE 65536 + typedef struct state { union { struct { @@ -57,6 +59,8 @@ typedef struct state { uint8_t *binary; unsigned binary_size; + uint8_t memory[MEMORY_SIZE]; + struct { unsigned imm_idx; // A bunch of unsigneds to store temporary operands and return them as pointers. @@ -64,3 +68,8 @@ typedef struct state { unsigned operand_holder[5]; } parse_data; } state_t; + +typedef struct { + uint16_t source; + uint16_t type; +} syscall_t;