From 3b6381f98156d960976c38fead9ecda51a51ea0e Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Sat, 13 Jan 2024 22:18:26 +0700 Subject: [PATCH] Part01-02: More mov instructions being handled --- asm_files/01-02-39.asm | 35 +++++++ asm_files/01-02-40.asm | 26 +++++ decode.c | 215 +++++++++++++++++++++++++++++++++-------- 3 files changed, 236 insertions(+), 40 deletions(-) create mode 100644 asm_files/01-02-39.asm create mode 100644 asm_files/01-02-40.asm diff --git a/asm_files/01-02-39.asm b/asm_files/01-02-39.asm new file mode 100644 index 0000000..113e7f1 --- /dev/null +++ b/asm_files/01-02-39.asm @@ -0,0 +1,35 @@ +; ======================================================================== +; LISTING 39 +; ======================================================================== + +bits 16 + +; Register-to-register +mov si, bx +mov dh, al + +; 8-bit immediate-to-register +mov cl, 12 +mov ch, -12 + +; 16-bit immediate-to-register +mov cx, 12 +mov cx, -12 +mov dx, 3948 +mov dx, -3948 + +; Source address calculation +mov al, [bx + si] +mov bx, [bp + di] +mov dx, [bp] + +; Source address calculation plus 8-bit displacement +mov ah, [bx + si + 4] + +; Source address calculation plus 16-bit displacement +mov al, [bx + si + 4999] + +; Dest address calculation +mov [bx + di], cx +mov [bp + si], cl +mov [bp], ch diff --git a/asm_files/01-02-40.asm b/asm_files/01-02-40.asm new file mode 100644 index 0000000..2599ccf --- /dev/null +++ b/asm_files/01-02-40.asm @@ -0,0 +1,26 @@ +; ======================================================================== +; LISTING 40 +; ======================================================================== + +bits 16 + +; Signed displacements +mov ax, [bx + di - 37] +mov [si - 300], cx +mov dx, [bx - 32] + +; Explicit sizes +mov [bp + di], byte 7 +mov [di + 901], word 347 + +; Direct address +mov bp, [5] +mov bx, [3458] + +; Memory-to-accumulator test +mov ax, [2555] +mov ax, [16] + +; Accumulator-to-memory test +mov [2554], ax +mov [15], ax diff --git a/decode.c b/decode.c index 6b6f697..e28eaf7 100644 --- a/decode.c +++ b/decode.c @@ -6,43 +6,53 @@ enum Instruction { - INST_MOV = 0b10001000 + INST_MOV_REG_REG = 0b10001000, + // INST_MOV_REG_REG = 0b10001000, + // INST_MOV_REG_REG = 0b10001000, }; enum Mode { - MODE_MEM_NOD = 0b00, - MODE_MEM_08D = 0b01, - MODE_MEM_16D = 0b10, - MODE_REGMODE = 0b11, + MODE_MEM_NO_DIS = 0b00, + MODE_MEM_DIS_08 = 0b01, + MODE_MEM_DIS_16 = 0b10, + MODE_RGSTR_MODE = 0b11, }; typedef struct Register { char code; - char *fullname; - char *bytename; - union { - struct { + 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" }, + {.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) +char* memory[65536]; + +// void inst_mov_rgmm_reg() + +int main(int argc, char** argv) { if (argc < 2) { @@ -56,41 +66,166 @@ int main(int argc, char **argv) perror("fopen\n"); return EXIT_FAILURE; } - size_t bytes_read = fread(buf, sizeof(*buf), ARRAY_SIZE(buf), f); + size_t bytes_read; printf("; Decoded 8086 Assembly Instructions\n\n"); printf("bits 16\n\n"); - for (int i = 0; i < (int)bytes_read; i += 2) + + while ((bytes_read = fread(buf, sizeof(char), 1, f)) > 0) { - char low_byte = buf[i]; - char high_byte = buf[i+1]; - char w = low_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) + char inst = buf[0]; + // Instruction instruction = 0; + // Register/memory to/from register + if ((inst & ~0x3) == (char)0b10001000) { - case INST_MOV: - if (mod == MODE_REGMODE) + // TODO: We should add some form of error handling here + bytes_read = fread(buf, sizeof(char), 1, f); + char next_byte = buf[0]; + char w = inst & 0b00000001; + char d = inst & 0b00000010; + 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) { - if (w == 1) + 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); + } + else + { + // char* src_name = w == 1 ? src_reg.fullname : src_reg.bytename; + char *dst_name; + if (d) { - printf("mov %s, %s", dst_reg.fullname, src_reg.fullname); + dst_name = w == 1 ? dst_reg.fullname : dst_reg.bytename; } else { - printf("mov %s, %s", dst_reg.bytename, src_reg.bytename); + dst_name = w == 1 ? src_reg.fullname : src_reg.bytename; + } + char* src_name; + switch (rm) + { + case 0b000: + src_name = "bx + si"; + break; + case 0b001: + src_name = "bx + di"; + break; + case 0b010: + src_name = "bp + si"; + break; + case 0b011: + src_name = "bp + di"; + break; + case 0b100: + src_name = "si"; + break; + case 0b101: + src_name = "di"; + break; + case 0b110: + src_name = "bp"; + break; + case 0b111: + src_name = "bx"; + break; + } + 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); + } + char disp_lo = buf[0]; + char disp_hi = buf[1]; + (void)disp_lo; + (void)disp_hi; + } + 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); + } } } - break; - default: - perror("Unrecognized Instruction\n"); } + // Immediate to register/memory + else if ((inst & ~0x1) == (char)0b11000110) + { + printf("mov imm to reg/mem"); + } + // Immediate to register + else if ((inst & ~0xF) == (char)0b10110000) + { + char w = inst & 0b00001000; + 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]); + } + } + // Memory to accumulator + else if ((inst & ~0x1) == (char)0b10100000) + { + printf("mov mem to acc"); + } + // Accumulator to memory + else if ((inst & ~0x1) == (char)0b10100010) + { + printf("mov acc to mem"); + } + // Register/memory to segment register + else if (inst == (char)0b10001110) + { + printf("mov regmem to segreg"); + } + // Segment register to register/memory + else if (inst == (char)0b10001100) + { + printf("mov segreg to regmem"); + } + else + { + fprintf(stderr, "Unrecognized Instruction"); + } + printf("\n"); } }