diff --git a/asm_files/01-01-37.asm b/asm_files/01-01-37.asm index d7361c1..723f3e9 100644 --- a/asm_files/01-01-37.asm +++ b/asm_files/01-01-37.asm @@ -4,4 +4,4 @@ bits 16 -mov bx, cx ; mov 001, 011 +mov cx, bx ; mov 001, 011 diff --git a/decode.c b/decode.c index c25cfb1..f190adc 100644 --- a/decode.c +++ b/decode.c @@ -1,5 +1,6 @@ #include #include +#include "lib.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) @@ -8,22 +9,6 @@ enum Instruction INST_MOV = 0b10001000 }; -enum Register -{ - REG_AL_AX = 0b000, - REG_CL_CX = 0b001, - REG_DL_DX = 0b010, - REG_BL_BX = 0b011, - REG_AH_SP = 0b100, - REG_CH_BP = 0b101, - REG_DH_SI = 0b110, - REG_BH_DI = 0b111, -}; - -#define REG_AX "ax" -#define REG_CX "cx" -#define REG_BX "bx" - enum Mode { MODE_MEM_NOD = 0b00, @@ -32,6 +17,31 @@ enum Mode MODE_REGMODE = 0b11, }; +typedef struct Register +{ + char code; + char *fullname; + char *bytename; + union { + struct { + char low; + char high; + }; + u16 full; + } value; +} Register; + +Register registers[8] = { + {.code = 0b000, .fullname = "ax", .bytename = "al" }, + {.code = 0b001, .fullname = "cx", .bytename = "cl" }, + {.code = 0b010, .fullname = "dx", .bytename = "dl" }, + {.code = 0b011, .fullname = "bx", .bytename = "bl" }, + {.code = 0b100, .fullname = "sp", .bytename = "ah" }, + {.code = 0b101, .fullname = "bp", .bytename = "ch" }, + {.code = 0b110, .fullname = "si", .bytename = "dh" }, + {.code = 0b111, .fullname = "di", .bytename = "bh" }, +}; + int main(int argc, char **argv) { if (argc < 2) @@ -52,42 +62,23 @@ int main(int argc, char **argv) printf("bits 16\n\n"); for (int i = 0; i < (int)bytes_read / 2; i += 2) { - char byte = buf[i]; - switch (byte & 0b11111100) + char low_byte = buf[i]; + char high_byte = buf[i+1]; + // char w = byte & 0b00000001; + char d = low_byte & 0b00000010; + char mod = (high_byte & 0b11000000) >> 6; + char reg = (high_byte & 0b00111000) >> 3; + char r_m = (high_byte & 0b00000111); + size_t reg_idx = reg; + size_t r_m_idx = r_m; + Register src_reg = d == 0 ? registers[reg_idx] : registers[r_m_idx]; + Register dst_reg = d == 0 ? registers[r_m_idx] : registers[reg_idx]; + switch (low_byte & 0b11111100) { case INST_MOV: - char high_byte = buf[i+1]; - // char w = byte & 0b00000001; - // char d = byte & 0b00000010; - char mod = (high_byte & 0b11000000) >> 6; - char reg = (high_byte & 0b00111000) >> 3; - char r_m = (high_byte & 0b00000111); - printf("mov "); if (mod == MODE_REGMODE) { - char *dest_reg_name = NULL; - switch (r_m) - { - case REG_CL_CX: - dest_reg_name = REG_CX; - break; - case REG_BL_BX: - dest_reg_name = REG_BX; - break; - } - printf("%s, ", dest_reg_name); - - char *src_reg_name = NULL; - switch (reg) - { - case REG_CL_CX: - src_reg_name = REG_CX; - break; - case REG_BL_BX: - src_reg_name = REG_BX; - break; - } - printf("%s", src_reg_name); + printf("mov %s, %s", dst_reg.fullname, src_reg.fullname); } break; default: diff --git a/lib.h b/lib.h new file mode 100644 index 0000000..bebd135 --- /dev/null +++ b/lib.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef int16_t i16; +typedef int32_t i32; +typedef uint32_t u32; +typedef uint64_t u64; +typedef float f32; +typedef double f64; +typedef uintptr_t uptr; +typedef char sbyte; +typedef ptrdiff_t size; +typedef size_t usize; + +#define OPTION(type, typeName) \ + struct { \ + enum {NONE, SOME} tag; \ + union { \ + u8 none; \ + type typeName; \ + } some; \ + } +