#include #include #include "lib.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) enum Instruction { INST_MOV = 0b10001000 }; enum Mode { MODE_MEM_NOD = 0b00, MODE_MEM_08D = 0b01, MODE_MEM_16D = 0b10, 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) { printf("Usage: Please provide assembled instructions as input\n"); exit(0); } unsigned char buf[256]; FILE *f = fopen(argv[1], "r"); if (!f) { perror("fopen\n"); return EXIT_FAILURE; } size_t bytes_read = fread(buf, sizeof(*buf), ARRAY_SIZE(buf), f); printf("; Decoded 8086 Assembly Instructions\n\n"); printf("bits 16\n\n"); for (int i = 0; i < (int)bytes_read / 2; i += 2) { 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: if (mod == MODE_REGMODE) { printf("mov %s, %s", dst_reg.fullname, src_reg.fullname); } break; default: perror("Unrecognized Instruction\n"); } } printf("\n"); }