#include #include #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 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, MODE_MEM_08D = 0b01, MODE_MEM_16D = 0b10, MODE_REGMODE = 0b11, }; 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 byte = buf[i]; switch (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); } break; default: perror("Unrecognized Instruction\n"); } } printf("\n"); }