diff --git a/8086_assembly_01/.gitignore b/8086_assembly_01/.gitignore new file mode 100644 index 0000000..19b2464 --- /dev/null +++ b/8086_assembly_01/.gitignore @@ -0,0 +1,3 @@ +dasm +listing_0037_single_register_mov +listing_0038_many_register_mov diff --git a/8086_assembly_01/Makefile b/8086_assembly_01/Makefile new file mode 100644 index 0000000..46770a1 --- /dev/null +++ b/8086_assembly_01/Makefile @@ -0,0 +1,2 @@ +all: + clang++ -g dasm.cpp -o dasm diff --git a/8086_assembly_01/dasm.cpp b/8086_assembly_01/dasm.cpp new file mode 100644 index 0000000..6695545 --- /dev/null +++ b/8086_assembly_01/dasm.cpp @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include + +// Bit patterns for the 8086 OPCODES +enum class OPCODES { + MOV = 0x88, +}; + +enum class OPMASKS { + MOV = 0xfc, +}; + +enum class FLAGS { + WORD = 0x01, + REG_DEST = 0x02, +}; + +enum class MODE { + MEM = 0x00, + MEM8 = 0x40, + MEM16 = 0x80, + REG = 0xc0, +}; + +uint16_t decode_mode(uint16_t instruction); +void decode_register(uint16_t instruction, bool word, char *dest); + +int main(int argc, char *argv[]) { + if (argc < 2) { + printf("Please provide a file to disassemble\n"); + return 1; + } + + const char *filename = argv[1]; + + FILE *fp = fopen(filename, "rb"); + + if (fp) { + uint16_t inst = 0; + const char *op = ""; + + char out_filename[4096] = {0}; + sprintf(out_filename, "%s_out.asm", filename); + + FILE *out = fopen(out_filename, "w"); + + if (out) { + fprintf(out, "; Disassembled by DASM\n\nbits 16\n\n"); + + while (fread(&inst, sizeof(inst), 1, fp)) { + if ((inst & (uint16_t)OPMASKS::MOV) == (uint16_t)OPCODES::MOV) { + op = "mov"; + + bool reg_dest = + (inst & (uint16_t)FLAGS::REG_DEST) == (uint16_t)FLAGS::REG_DEST; + bool word = (inst & (uint16_t)FLAGS::WORD) == (uint16_t)FLAGS::WORD; + + // NOTE: Using right shift will only work on little-endian CPUs + uint16_t operands_info = inst >> 8; + + if (decode_mode(operands_info) == (uint16_t)MODE::REG) { + char rm[3] = {0}; + char reg[3] = {0}; + + decode_register(operands_info, word, rm); + decode_register(operands_info >> 3, word, reg); + + fprintf(out, "%s %s, %s\n", op, reg_dest ? reg : rm, + reg_dest ? rm : reg); + } + } else { + printf("It's not a mov operation\n"); + } + } + + fclose(out); + } else { + printf("Failed to open output file\n"); + } + + fclose(fp); + } else { + printf("Failed to open the selected file\n"); + } + + return 0; +} + +uint16_t decode_mode(uint16_t instruction) { + uint16_t mode_mask = 0xc0; + + return instruction & mode_mask; +} + +void decode_register(uint16_t instruction, bool word, char *dest) { + uint16_t reg_mask = 0x07; + + switch (instruction & reg_mask) { + case 0x00: + if (word) { + strcpy(dest, "ax"); + } else { + strcpy(dest, "al"); + } + break; + case 0x01: + if (word) { + strcpy(dest, "cx"); + } else { + strcpy(dest, "cl"); + } + break; + case 0x02: + if (word) { + strcpy(dest, "dx"); + } else { + strcpy(dest, "dl"); + } + break; + case 0x03: + if (word) { + strcpy(dest, "bx"); + } else { + strcpy(dest, "bl"); + } + break; + case 0x04: + if (word) { + strcpy(dest, "sp"); + } else { + strcpy(dest, "ah"); + } + break; + case 0x05: + if (word) { + strcpy(dest, "bp"); + } else { + strcpy(dest, "ch"); + } + break; + case 0x06: + if (word) { + strcpy(dest, "si"); + } else { + strcpy(dest, "dh"); + } + break; + case 0x07: + if (word) { + strcpy(dest, "di"); + } else { + strcpy(dest, "bh"); + } + break; + } +} diff --git a/8086_assembly_01/listing_0037_single_register_mov.asm b/8086_assembly_01/listing_0037_single_register_mov.asm new file mode 100644 index 0000000..a20862f --- /dev/null +++ b/8086_assembly_01/listing_0037_single_register_mov.asm @@ -0,0 +1,19 @@ +; ======================================================================== +; +; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved. +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Please see https://computerenhance.com for further information +; +; ======================================================================== */ + +; ======================================================================== +; LISTING 37 +; ======================================================================== + +bits 16 + +mov cx, bx diff --git a/8086_assembly_01/listing_0037_single_register_mov_out.asm b/8086_assembly_01/listing_0037_single_register_mov_out.asm new file mode 100644 index 0000000..5952bb9 --- /dev/null +++ b/8086_assembly_01/listing_0037_single_register_mov_out.asm @@ -0,0 +1,5 @@ +; Disassembled by DASM + +bits 16 + +mov cx, bx diff --git a/8086_assembly_01/listing_0038_many_register_mov.asm b/8086_assembly_01/listing_0038_many_register_mov.asm new file mode 100644 index 0000000..7431c2f --- /dev/null +++ b/8086_assembly_01/listing_0038_many_register_mov.asm @@ -0,0 +1,29 @@ +; ======================================================================== +; +; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved. +; +; This software is provided 'as-is', without any express or implied +; warranty. In no event will the authors be held liable for any damages +; arising from the use of this software. +; +; Please see https://computerenhance.com for further information +; +; ======================================================================== */ + +; ======================================================================== +; LISTING 38 +; ======================================================================== + +bits 16 + +mov cx, bx +mov ch, ah +mov dx, bx +mov si, bx +mov bx, di +mov al, cl +mov ch, ch +mov bx, ax +mov bx, si +mov sp, di +mov bp, ax diff --git a/8086_assembly_01/listing_0038_many_register_mov_out.asm b/8086_assembly_01/listing_0038_many_register_mov_out.asm new file mode 100644 index 0000000..764df33 --- /dev/null +++ b/8086_assembly_01/listing_0038_many_register_mov_out.asm @@ -0,0 +1,15 @@ +; Disassembled by DASM + +bits 16 + +mov cx, bx +mov ch, ah +mov dx, bx +mov si, bx +mov bx, di +mov al, cl +mov ch, ch +mov bx, ax +mov bx, si +mov sp, di +mov bp, ax