From 094733ee7015fa4f02dc6fb9ca2870ac1f990a54 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Mon, 15 Jan 2024 10:45:08 +0700 Subject: [PATCH] MOV inst conditional branching cleaned up considerably, cause god it was ugly --- decode.c | 119 ++++++++++++++++++++++++------------------------------- 1 file changed, 51 insertions(+), 68 deletions(-) diff --git a/decode.c b/decode.c index ef81c69..a42113b 100644 --- a/decode.c +++ b/decode.c @@ -89,6 +89,16 @@ char* get_eac_registers(char rm) return reg_name; } +static inline char *reg_name(Register reg, char wide) +{ + return wide == 1 ? reg.fullname : reg.bytename; +} + +static inline i16 get_data(unsigned char *buf, char wide) +{ + return wide == 1 ? (i16)buf[1] << 8 | buf[0] : buf[0]; +} + int main(int argc, char** argv) { if (argc < 2) @@ -103,6 +113,7 @@ int main(int argc, char** argv) perror("fopen\n"); return EXIT_FAILURE; } + size_t bytes_read; printf("; Decoded 8086 Assembly Instructions\n\n"); @@ -119,69 +130,34 @@ int main(int argc, char** argv) bytes_read = fread(buf, sizeof(char), 1, f); char next_byte = buf[0]; char w = inst & 0b00000001; - char d = inst & 0b00000010; + char d = (inst & 0b00000010) >> 1; char mod = (next_byte & 0b11000000) >> 6; char reg = (next_byte & 0b00111000) >> 3; char rm = (next_byte & 0b00000111); size_t reg_idx = reg; size_t rm_idx = rm; - Register src_reg = d == 0 ? registers[reg_idx] : registers[rm_idx]; - Register dst_reg = d == 0 ? registers[rm_idx] : registers[reg_idx]; if (mod == MODE_RGSTR_MODE) { - char* src_name = w == 1 ? src_reg.fullname : src_reg.bytename; - char* dst_name = w == 1 ? dst_reg.fullname : dst_reg.bytename; - printf("mov %s, %s", dst_name, src_name); + Register src_reg = d == 0 ? registers[reg_idx] : registers[rm_idx]; + Register dst_reg = d == 0 ? registers[rm_idx] : registers[reg_idx]; + printf("mov %s, %s ;0", reg_name(dst_reg, w), reg_name(src_reg, w)); } else { - // char* src_name = w == 1 ? src_reg.fullname : src_reg.bytename; - char *dst_name; - if (d) + // This is a trick because mod == 1 and mod == 2 will displace one and two bytes + // respectively but mod == 3 wraps to 0 since it doesn't displace + int bytes_to_read = mod % 3; + bytes_read = fread(buf, sizeof(char), bytes_to_read, f); + char* eac_name = get_eac_registers(rm); + char disp_buf[16] = {'\0'}; + if (bytes_to_read > 0) { - dst_name = w == 1 ? dst_reg.fullname : dst_reg.bytename; - } - else - { - dst_name = w == 1 ? src_reg.fullname : src_reg.bytename; - } - char* src_name = get_eac_registers(rm); - if (mod == MODE_MEM_DIS_16) - { - bytes_read = fread(buf, sizeof(char), 2, f); - i16 data = (i16)buf[1] << 8 | buf[0]; - if (d) - { - printf("mov %s, [%s + %d] ;(mod %d, w %d, d %d)", dst_name, src_name, data, mod, d, w); - } - else - { - printf("mov [%s], %s ;(mod %d, w %d, d %d)", src_name, dst_name, mod, d, w); - } - } - else if (mod == MODE_MEM_DIS_08) - { - bytes_read = fread(buf, sizeof(char), 1, f); - if (d) - { - printf("mov %s, [%s + %d] ;(mod %d, w %d, d %d)", dst_name, src_name, buf[0], mod, d, w); - } - else - { - printf("mov [%s], %s ;(mod %d, w %d, d %d)", src_name, dst_name, mod, d, w); - } - } - else if (mod == MODE_MEM_NO_DIS) - { - if (d) - { - printf("mov %s, [%s] ;(mod %d, w %d, d %d)", dst_name, src_name, mod, d, w); - } - else - { - printf("mov [%s], %s ;(mod %d, w %d, d %d)", src_name, dst_name, mod, d, w); - } + i16 disp = get_data(buf, bytes_to_read - 1); + if (disp > 0) sprintf(disp_buf, " %s %d", disp >= 0 ? "+" : "-", abs(disp)); } + Register reg = registers[reg_idx]; + if (d) printf("mov %s, [%s%s] ;1", reg_name(reg, w), eac_name, disp_buf); + else printf("mov [%s%s], %s ;2", eac_name, disp_buf, reg_name(reg, w)); } } // Immediate to register/memory @@ -193,34 +169,41 @@ int main(int argc, char** argv) char rm = (buf[0] & 0b00000111); int bytes_to_read = 1; bytes_to_read += w == 0 ? 0 : 1; - // This is a trick because mod == 1 and mod == 2 will displace one and two bytes - // respectively but mod == 3 wraps to 0 since it doesn't displace + // Same trick from earlier, see comment bytes_to_read += mod % 3; bytes_read = fread(buf, sizeof(char), bytes_to_read, f); char *eac_name = get_eac_registers(rm); char *data_ptr = (char*)buf + (char)bytes_to_read - (w == 0 ? 1 : 2); i16 data = w == 0 ? data_ptr[0] : (i16)data_ptr[1] << 8 | data_ptr[0]; char *word = w == 0 ? "byte" : "word"; - char *disp = mod == 1 || mod == 2 ? sprintf(); - printf("mov [%s], %s %d w %d mod %d rm %d", eac_name, word, data, w, mod, rm); + char disp_str[16]; + if (mod > 0 && mod < 3) + { + if (mod == 1) + { + sprintf(disp_str, " + %d", buf[1]); + } + else + { + i16 disp = (i16)buf[1] << 8 | buf[0]; + sprintf(disp_str, " + %d", disp); + } + } + else + { + disp_str[0] = '\0'; + } + + printf("mov [%s%s], %s %d ;w %d mod %d rm %d", eac_name, disp_str, word, data, w, mod, rm); } // Immediate to register else if ((inst & ~0xF) == (char)0b10110000) { - char w = inst & 0b00001000; + char w = (inst & 0b00001000) >> 3; Register reg = registers[(size_t)inst & 0b00000111]; - char *reg_name = w == 0 ? reg.bytename : reg.fullname; - if (w) - { - bytes_read = fread(buf, sizeof(char), 2, f); - i16 data = (i16)buf[1] << 8 | buf[0]; - printf("mov %s, %hd ; Immediate to register", reg_name, data); - } - else - { - bytes_read = fread(buf, sizeof(char), 1, f); - printf("mov %s, %d ; Immediate to register", reg_name, (sbyte)buf[0]); - } + char bytes_to_read = w == 1 ? 2 : 1; + bytes_read = fread(buf, sizeof(char), bytes_to_read, f); + printf("mov %s, %hd ; Immediate to register", reg_name(reg, w), get_data(buf, w)); } // Memory to accumulator else if ((inst & ~0x1) == (char)0b10100000)