From 873159c5ee3f09cfb537de2d5795b467a6fbaf36 Mon Sep 17 00:00:00 2001 From: Hane Date: Tue, 27 Jan 2026 20:06:39 +0100 Subject: [PATCH] 1-3: All arithmetics complete --- 1-1/compile.sh | 3 +- 1-1/nasm-compile.sh | 7 +- 1-2/compile.sh | 3 +- 1-2/listing-40 | Bin 51 -> 64 bytes 1-2/nasm-compile.sh | 5 +- 1-3/8086coded | Bin 0 -> 35808 bytes 1-3/compile.sh | 4 + 1-3/decoder.c | 925 ++++++++++++++++++++++++++++++++++++++++++++ 1-3/listing-41 | Bin 0 -> 76 bytes 1-3/listing-41.asm | 121 ++++++ 1-3/nasm-compile.sh | 5 + 1-3/output.asm | 0 12 files changed, 1066 insertions(+), 7 deletions(-) create mode 100755 1-3/8086coded create mode 100755 1-3/compile.sh create mode 100644 1-3/decoder.c create mode 100644 1-3/listing-41 create mode 100644 1-3/listing-41.asm create mode 100755 1-3/nasm-compile.sh create mode 100644 1-3/output.asm diff --git a/1-1/compile.sh b/1-1/compile.sh index e3ecbb0..fff3fa0 100755 --- a/1-1/compile.sh +++ b/1-1/compile.sh @@ -1,3 +1,4 @@ #! /usr/bin/env bash +SCRIPT_LOC=$( dirname -- $( readlink -f -- "$0"; )) -gcc 1-1/decoder.c -O0 -g -gdwarf -o 1-1/8086coded +gcc $SCRIPT_LOC/decoder.c -O0 -g -gdwarf -o $SCRIPT_LOC/8086coded diff --git a/1-1/nasm-compile.sh b/1-1/nasm-compile.sh index 4dcedb9..596c0c4 100644 --- a/1-1/nasm-compile.sh +++ b/1-1/nasm-compile.sh @@ -1,4 +1,5 @@ -#! /usr/env/bin bash +#! /usr/bin/env bash +SCRIPT_LOC=$( dirname -- $( readlink -f -- "$0"; )) -nasm -f bin 1-1/listing-38.asm -o 1-1/listing-37 -nasm -f bin 1-1/listing-38.asm -o 1-1/listing-38 +nasm -f bin $SCRIPT_LOC/listing-39.asm -o $SCRIPT_LOC/listing-39 +nasm -f bin $SCRIPT_LOC/listing-40.asm -o $SCRIPT_LOC/listing-40 diff --git a/1-2/compile.sh b/1-2/compile.sh index 04ac9ca..fff3fa0 100755 --- a/1-2/compile.sh +++ b/1-2/compile.sh @@ -1,3 +1,4 @@ #! /usr/bin/env bash +SCRIPT_LOC=$( dirname -- $( readlink -f -- "$0"; )) -gcc 1-2/decoder.c -O0 -g -gdwarf -o 1-2/8086coded +gcc $SCRIPT_LOC/decoder.c -O0 -g -gdwarf -o $SCRIPT_LOC/8086coded diff --git a/1-2/listing-40 b/1-2/listing-40 index 13c1744e507a65be23dc6a3c380158513f216d52..3610804fdbf1e4e0f7ff1d14df333e0b71ad4e16 100644 GIT binary patch delta 18 ZcmXqZ;O%yw)7>udr`!E+w>$F$V*o@h2Ydhk delta 5 McmZ=Tp2%wq00a>MMF0Q* diff --git a/1-2/nasm-compile.sh b/1-2/nasm-compile.sh index a4c0a5a..596c0c4 100755 --- a/1-2/nasm-compile.sh +++ b/1-2/nasm-compile.sh @@ -1,4 +1,5 @@ #! /usr/bin/env bash +SCRIPT_LOC=$( dirname -- $( readlink -f -- "$0"; )) -nasm -f bin 1-2/listing-39.asm -o 1-2/listing-39 -nasm -f bin 1-2/listing-40.asm -o 1-2/listing-40 +nasm -f bin $SCRIPT_LOC/listing-39.asm -o $SCRIPT_LOC/listing-39 +nasm -f bin $SCRIPT_LOC/listing-40.asm -o $SCRIPT_LOC/listing-40 diff --git a/1-3/8086coded b/1-3/8086coded new file mode 100755 index 0000000000000000000000000000000000000000..7bb389004b29a28fae61e4aedd0032524a46ff7c GIT binary patch literal 35808 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 Pa3?Rcbx{OSP3^w`h;2f@ literal 0 HcmV?d00001 diff --git a/1-3/compile.sh b/1-3/compile.sh new file mode 100755 index 0000000..fff3fa0 --- /dev/null +++ b/1-3/compile.sh @@ -0,0 +1,4 @@ +#! /usr/bin/env bash +SCRIPT_LOC=$( dirname -- $( readlink -f -- "$0"; )) + +gcc $SCRIPT_LOC/decoder.c -O0 -g -gdwarf -o $SCRIPT_LOC/8086coded diff --git a/1-3/decoder.c b/1-3/decoder.c new file mode 100644 index 0000000..ffcb8d8 --- /dev/null +++ b/1-3/decoder.c @@ -0,0 +1,925 @@ +#include +#include +#include +#include +#include + +//TODO: Pass file struct and currently read bytes via param + +/* typedef enum ARITHMETIC_OP */ +/* { */ +/* ADD = 0b000, */ +/* ADC = 0b010, */ +/* SUB_NEG_IMUL = 0b101, */ +/* SBB = 0b011, */ +/* MUL = 0b100, */ +/* DEC = 0b001, */ +/* CMP = 0b111, */ +/* } ARITHMETIC_OP; */ + +typedef enum ARITHMETIC_OP +{ + ADD = 0b000, + CMP = 0b111, + SUB = 0b101 +} ARITHMETIC_OP; + +#define ARITHMETIC_OP_TXT_LEN 4 +char ARITHMETIC_OP_TXT[0b1000][ARITHMETIC_OP_TXT_LEN] = { [0b000] = "add", [0b111] = "cmp", [0b101] = "sub" }; + +typedef enum ASC_INST_MASK +{ + ASC_REGM_R_M = 0b1100'01 , //d w + // ASC_I_RM = 0b1111'11, //s w + ASC_I_A_M = 0b1100'011 //w +} ARITHMETIC_INST_MASK; + +typedef enum ASC_INST +{ + ASC_REGM_R = 0b0, //d w + ASC_I_RM = 0b1000'00, //s w + ASC_I_A = 0b0000'010 //w +} ARITHMETIC_INST; + +typedef enum DT_INSTRUCTIONS +{ + MOV_RM_TF_R = 0b1000'10, //d w + MOV_I_T_RM = 0b1100'011, // w + MOV_I_T_R = 0b1011, // w reg + MOV_M_T_A = 0b1010'000, // w + MOV_A_T_M = 0b1010'001, // w + MOV_RM_T_SR = 0b1000'1110, + MOV_SR_T_RM = 0b1000'1100, +} DT_INSTRUCTIONS; + +enum REGISTER_MOD + { + MEM_NO_DISP = 0b00, + MEM_8BIT_DISP = 0b01, + MEM_16BIT_DISP = 0b10, + REG_NO_DISP = 0b11 + }; + +#define REG_ENCODING_TXT_LEN 3 +char REG_ENCODING_TXT[0b10000][REG_ENCODING_TXT_LEN] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }; + +#define EA_ENCODING_TXT_LEN 8 +char EA_ENCODING_TXT[0b1000][EA_ENCODING_TXT_LEN] = { "bx + si", "bx + di", "bp + si", "bp + di", + "si", "di", "bp", "bx" }; + +#define WORD_SIGNAL_LEN 6 +char WORD_SIGNAL_TXT[0b10][WORD_SIGNAL_LEN] = { "byte ", "word " }; + +/* enum REG_ENCODING */ +/* { */ +/* R_AL = 0b000, */ +/* R_CL = 0b001, */ +/* R_DL = 0b010, */ +/* R_BL = 0b011, */ +/* R_AH = 0b100, */ +/* R_CH = 0b101, */ +/* R_DH = 0b110, */ +/* R_BH = 0b111 */ +/* }; */ + +/* enum WREG_ENCODING */ +/* { */ +/* WR_AX = 0b000, */ +/* WR_CX = 0b001, */ +/* WR_DX = 0b010, */ +/* WR_BX = 0b011, */ +/* WR_SP = 0b100, */ +/* WR_BP = 0b101, */ +/* WR_SI = 0b110, */ +/* WR_DI = 0b111 */ +/* }; */ + +typedef struct +{ + FILE *binary; + uint64_t size; +} binary_data; + +FILE *output; +binary_data bin; + +int MOV_MA_T_AM_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read, bool is_M_T_A) +{ + const uint8_t wide_mask = 0b0000'0001; + uint8_t extra_bytes_read; + unsigned char byte[1]; + uint8_t acc_wide = 0; + uint8_t high_addr = 0; + uint16_t word_addr = byte2; + + int disp_len = 0; + char ea_string[18] = {'\0'}; + char *ea_string_write_ptr = ea_string; + + //Immediate value retrieval + if (wide_mask & byte1) + { + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + high_addr = (uint8_t)byte[0]; + word_addr = word_addr + (high_addr << 8); + } + + //target reg retrieval + acc_wide = (((byte1 & wide_mask)) * 8); + + //Stringify address + //EA STRING GENERATION + *ea_string_write_ptr = '['; + ea_string_write_ptr++; + disp_len = sprintf(ea_string_write_ptr, "%d", word_addr); + ea_string_write_ptr += disp_len; + *ea_string_write_ptr = ']'; + //END + + printf("%s %s, %s\n", "mov", is_M_T_A ? REG_ENCODING_TXT[acc_wide] : ea_string, + is_M_T_A ? ea_string : REG_ENCODING_TXT[acc_wide]); + fprintf(output, "%s %s, %s\n", "mov", is_M_T_A ? REG_ENCODING_TXT[acc_wide] : ea_string, + is_M_T_A ? ea_string : REG_ENCODING_TXT[acc_wide]); + + return extra_bytes_read; +} + +int MOV_I_T_R_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read) +{ + const uint8_t wide_mask = 0b0000'1000; + const uint8_t reg_mask = 0b0000'0111; + unsigned char byte[1]; + uint8_t extra_bytes_read = 0; + uint16_t full_im = byte2; + uint8_t high_im = 0; + uint8_t reg_value = 0; + + //Immediate value retrieval + if (wide_mask & byte1) + { + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + high_im = (uint8_t)byte[0]; + full_im = full_im + (high_im << 8); + } + + //target reg retrieval + reg_value = (byte1 & reg_mask) + (((byte1 & wide_mask) >> 3) * 8); + + printf("%s %s, %d\n", "mov", REG_ENCODING_TXT[reg_value], full_im); + fprintf(output, "%s %s, %d\n", "mov", REG_ENCODING_TXT[reg_value], full_im); + + return extra_bytes_read; +} + +typedef struct { + char* string; + uint64_t len; +} output_string; + +void fill_ea_string(output_string *str, char* content, int16_t displacement) +{ + //EA STRING GENERATION + char* str_beg = str->string; + uint64_t disp_len = 0; + + *(str->string) = '['; + str->string++; + str->len++; + memcpy(str->string, content, strlen(content)); + str->string += strlen(content); + str->len += strlen(content); + if (displacement) + { + if (strlen(content) > 0) + { + *(str->string) = ' '; + if(displacement >= 0) + { + *(str->string + 1) = '+'; + *(str->string + 2) = ' '; + str->string += 3; + str->len += 3; + } + else + { + str->string += 1; + str->len += 1; + } + } + disp_len = sprintf(str->string, "%d", displacement); + str->string += disp_len; + str->len += disp_len; + } + *(str->string) = ']'; + str->string = str_beg; + str->len += 2; + //END + + return; +} + +int MOV_I_T_RM_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read) +{ + const uint8_t wide_mask = 0b0000'0001; + const uint8_t mod_mask = 0b1100'0000; + const uint8_t regm_mask = 0b0000'0111; + + unsigned char byte[1]; + unsigned char payload[4]; + uint8_t high_disp = 0; + uint16_t wide_disp = 0; + uint8_t high_data = 0; + uint16_t wide_data = 0; + bool is_wide = wide_mask & byte1; + + uint8_t extra_bytes_read = 0; + + //Effective Address string compose vars + char ea_string[18] = {'\0'}; + char *ea_string_write_ptr = ea_string; + + //Immediate value string compose vars + output_string mem_data; + mem_data.len = 0; + mem_data.string = calloc(18, sizeof(char)); //"[bp + di + 65535]\0" + + //Number of chars disp value takes + int disp_len = 0; + enum REGISTER_MOD inst_mod = (byte2 & mod_mask) >> 6; + uint8_t extra_bytes = 1 + is_wide; + + uint8_t reg_value = 0; + uint8_t ea_table_value = (byte2 & regm_mask); + + switch (inst_mod) + { + case (REG_NO_DISP): + printf("Oh. This happened.\n"); + //This shouldn't happen, right? + break; + case (MEM_NO_DISP): + //If R/M equals 110, there actually is displacement to worry about + bool is_direct_address = (ea_table_value == 0b110); + if (is_direct_address) + extra_bytes += 1 + is_wide; + for (int i = 0; i < extra_bytes; i++) + { + fread(&(payload[i]), sizeof(byte), 1, bin.binary); + extra_bytes_read++; + } + + //Composing displacement and immediate values + //TODO: Data missing when 8bit data bug? + if (is_direct_address) + { + wide_disp = payload[0]; + if (is_wide) + { + wide_disp = (payload[1] << 8) + wide_disp; + wide_data = payload[2]; + wide_data = (payload[3] << 8) + wide_data; + } + else + { + wide_data = payload[1]; + } + } + else + { + wide_data = payload[0]; + if (is_wide) + wide_data = (payload[1] << 8) + wide_data; + } + fill_ea_string(&mem_data, (is_direct_address ? "" : EA_ENCODING_TXT[ea_table_value]), wide_disp); + printf("%s %s, %s%d\n", "mov", mem_data.string, WORD_SIGNAL_TXT[is_wide], wide_data); + fprintf(output, "%s %s, %s%d\n", "mov", mem_data.string, WORD_SIGNAL_TXT[is_wide], wide_data); + break; + case (MEM_8BIT_DISP): + //If R/M equals 110, there actually is displacement to worry about + extra_bytes += 1; + for (int i = 0; i < extra_bytes; i++) + { + fread(&(payload[i]), sizeof(byte), 1, bin.binary); + extra_bytes_read++; + } + + //Composing displacement and immediate values + wide_disp = payload[0]; + wide_data = payload[1]; + if (is_wide) + { + wide_data = (payload[2] << 8) + wide_data; + } + + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], wide_disp); + printf("%s %s, %s%d\n", "mov", mem_data.string, WORD_SIGNAL_TXT[is_wide], wide_data); + fprintf(output, "%s %s, %s%d\n", "mov", mem_data.string, WORD_SIGNAL_TXT[is_wide], wide_data); + break; + case (MEM_16BIT_DISP): + //If R/M equals 110, there actually is displacement to worry about + extra_bytes += 2; + for (int i = 0; i < extra_bytes; i++) + { + fread(&(payload[i]), sizeof(byte), 1, bin.binary); + extra_bytes_read++; + } + + //Composing displacement and immediate values + wide_disp = payload[0]; + wide_disp = (payload[1] << 8) + wide_disp; + + wide_data = payload[2]; + if (is_wide) + { + wide_data = (payload[3] << 8) + wide_data; + } + + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], wide_disp); + printf("%s %s, %s%d\n", "mov", mem_data.string, WORD_SIGNAL_TXT[is_wide], wide_data); + fprintf(output, "%s %s, %s%d\n", "mov", mem_data.string, WORD_SIGNAL_TXT[is_wide], wide_data); + break; + } + + return extra_bytes_read; +} + +int16_t calc_effective_disp(uint8_t high_order, uint8_t low_order, bool lo_only) +{ + const uint8_t low_order_neg_mask = 0b1000'0000; + int16_t effective_disp = 0; + + if (lo_only & ((low_order & low_order_neg_mask) >> 7)) + high_order = high_order | 0b1111'1111; + int8_t *effective_disp_high_order =(int8_t*) &(effective_disp) + 1; + memcpy(&(effective_disp), &low_order, 1); + memcpy(effective_disp_high_order, &high_order, 1); + return effective_disp; +} + +int MOV_RM_TF_R_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read) +{ + const uint8_t wide_mask = 0b0000'0001; + const uint8_t dest_mask = 0b0000'0010; + const uint8_t mod_mask = 0b1100'0000; + const uint8_t regm_mask = 0b0011'1000; + + unsigned char byte[1]; + uint8_t low_disp = 0; + uint8_t high_disp = 0; + uint16_t wide_disp = 0; + int16_t effective_disp = 0; + uint8_t extra_bytes_read = 0; + + output_string mem_data; + mem_data.len = 0; + mem_data.string = calloc(18, sizeof(char)); //"[bp + di + 65535]\0" + + bool reg_is_dest = (byte1 & dest_mask); + uint8_t inst_mod = (byte2 & mod_mask) >> 6; + + //Effective Address string compose vars + char ea_string[18] = {'\0'}; + char *ea_string_write_ptr = ea_string; + + //Number of chars disp value takes + int disp_len = 0; + + uint8_t reg_value = 0; + uint8_t ea_table_value = 0; + switch (inst_mod) + { + case (REG_NO_DISP): + //Since we're doing register mode/register to register, both reg and r/m are affected by the W bit + //if D=1, dest is retrieved from the reg field in byte2 and src from r/m + uint8_t dest_value = (reg_is_dest) ? ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8) + : (byte2 & (regm_mask >> 3)) + ((byte1 & wide_mask) * 8); + uint8_t src_value = (reg_is_dest) ? (byte2 & (regm_mask >> 3)) + ((byte1 & wide_mask) * 8) + : ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + printf("%s %s, %s\n", "mov", REG_ENCODING_TXT[dest_value], REG_ENCODING_TXT[src_value]); + fprintf(output, "%s %s, %s\n", "mov", REG_ENCODING_TXT[dest_value], REG_ENCODING_TXT[src_value]); + break; + case (MEM_8BIT_DISP): + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + low_disp = (uint8_t)byte[0]; + + reg_value = ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + ea_table_value = (byte2 & (regm_mask >> 3)); + effective_disp = calc_effective_disp(0, low_disp, true); + + //EA STRING GENERATION + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], effective_disp); + //END + + printf("%s %s, %s\n", "mov", (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + fprintf(output, "%s %s, %s\n", "mov", (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + break; + case (MEM_16BIT_DISP): + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + low_disp = (uint8_t)byte[0]; + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + high_disp = (uint8_t)byte[0]; + + //Composing wide displacement + effective_disp = calc_effective_disp(high_disp, low_disp, false); + + reg_value = ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + ea_table_value = (byte2 & (regm_mask >> 3)); + + //EA STRING GENERATION + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], effective_disp); + //END + + printf("%s %s, %s\n", "mov", (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + fprintf(output, "%s %s, %s\n", "mov", (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + break; + case (MEM_NO_DISP): + //Checking if special case 110 applies + ea_table_value = (byte2 & (regm_mask >> 3)); + //If R/M equals 110, there actually is displacement to worry about + bool is_direct_address = (ea_table_value == 0b110); + if (is_direct_address) + { + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + low_disp = (uint8_t)byte[0]; + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + high_disp = (uint8_t)byte[0]; + + //Composing wide displacement + wide_disp = high_disp << 8; + wide_disp = wide_disp | low_disp; + } + + reg_value = ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + + if (is_direct_address) + { + //EA STRING GENERATION + *ea_string_write_ptr = '['; + ea_string_write_ptr++; + disp_len = sprintf(ea_string_write_ptr, "%d", wide_disp); + ea_string_write_ptr += disp_len; + *ea_string_write_ptr = ']'; + //END + } + else + { + //EA STRING GENERATION + *ea_string_write_ptr = '['; + ea_string_write_ptr++; + memcpy(ea_string_write_ptr, EA_ENCODING_TXT[ea_table_value], strlen(EA_ENCODING_TXT[ea_table_value])); + ea_string_write_ptr += strlen(EA_ENCODING_TXT[ea_table_value]); + *ea_string_write_ptr = ']'; + //END + } + + printf("%s %s, %s\n", "mov", (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : ea_string) + , (reg_is_dest ? ea_string + : REG_ENCODING_TXT[reg_value])); + fprintf(output, "%s %s, %s\n", "mov", (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : ea_string) + , (reg_is_dest ? ea_string + : REG_ENCODING_TXT[reg_value])); + break; + } + return extra_bytes_read; +} + +int ASC_I_A_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read) +{ + const uint8_t wide_mask = 0b0000'0001; + const uint8_t op_mask = 0b0011'1000; + uint8_t extra_bytes_read = 0; + unsigned char byte[1]; + uint8_t acc_wide = 0; + uint8_t high_imm = 0; + int16_t effective_imm = 0; + + int disp_len = 0; + + //Arithmetic op retrieval + uint8_t a_op = (byte1 & op_mask) >> 3; + + //Immediate value retrieval + if (wide_mask & byte1) + { + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + high_imm = (uint8_t)byte[0]; + effective_imm = calc_effective_disp(high_imm, byte2, false); + } + else + effective_imm = calc_effective_disp(0, byte2, true); + + //target reg retrieval + acc_wide = (((byte1 & wide_mask)) * 8); + + printf("%s %s, %d\n", ARITHMETIC_OP_TXT[a_op], REG_ENCODING_TXT[acc_wide], effective_imm); + fprintf(output, "%s %s, %d\n", ARITHMETIC_OP_TXT[a_op], REG_ENCODING_TXT[acc_wide], effective_imm); + + return extra_bytes_read; +} + +int ASC_I_RM_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read) +{ + const uint8_t wide_mask = 0b0000'0001; + const uint8_t sign_mask = 0b0000'0010; + const uint8_t mod_mask = 0b1100'0000; + const uint8_t regm_mask = 0b0000'0111; + const uint8_t op_mask = 0b0011'1000; + + unsigned char byte[1]; + unsigned char payload[4]; + uint8_t low_disp = 0; + uint8_t high_disp = 0; + int16_t effective_disp = 0; + uint8_t low_data = 0; + uint8_t high_data = 0; + int16_t effective_data = 0; + bool is_wide = wide_mask & byte1; + bool is_sign = sign_mask & byte1; + + uint8_t extra_bytes_read = 0; + + //Arithmetic op retrieval + uint8_t a_op = (byte2 & op_mask) >> 3; + + //Immediate value string compose vars + output_string mem_data; + mem_data.len = 0; + mem_data.string = calloc(18, sizeof(char)); //"[bp + di + 65535]\0" + + //Number of chars disp value takes + int disp_len = 0; + enum REGISTER_MOD inst_mod = (byte2 & mod_mask) >> 6; + uint8_t extra_bytes = 1 + (is_wide && !is_sign); + + uint8_t ea_table_value = (byte2 & regm_mask); + uint8_t reg_value = ea_table_value; + + switch (inst_mod) + { + case (REG_NO_DISP): + for (int i = 0; i < extra_bytes; i++) + { + fread(&(payload[i]), sizeof(byte), 1, bin.binary); + extra_bytes_read++; + } + low_data = payload[0]; + if (is_wide && !is_sign) + { + high_data = payload[1]; + effective_data = calc_effective_disp(high_data, low_data, false); + } + else + { + effective_data = calc_effective_disp(0, low_data, true); + } + printf("%s %s, %d\n", ARITHMETIC_OP_TXT[a_op], REG_ENCODING_TXT[reg_value + (is_wide * 8)], effective_data); + fprintf(output, "%s %s, %d\n", ARITHMETIC_OP_TXT[a_op], REG_ENCODING_TXT[reg_value + (is_wide * 8)], effective_data); + break; + case (MEM_NO_DISP): + //If R/M equals 110, there actually is displacement to worry about + bool is_direct_address = (ea_table_value == 0b110); + if (is_direct_address) + extra_bytes += 1 + is_wide; + for (int i = 0; i < extra_bytes; i++) + { + fread(&(payload[i]), sizeof(byte), 1, bin.binary); + extra_bytes_read++; + } + + //Composing displacement and immediate values + if (is_direct_address) + { + low_disp = payload[0]; + high_disp = payload[1]; + effective_disp = calc_effective_disp(high_disp, low_disp, false); + low_data = payload[2]; + if (is_wide && !is_sign) + { + high_data = payload[3]; + effective_data = calc_effective_disp(high_data, low_data, false); + } + else + { + effective_data = calc_effective_disp(0, low_data, true); + } + } + else + { + low_data = payload[0]; + if (is_wide && !is_sign) + { + high_data = payload[1]; + effective_data = calc_effective_disp(high_data, low_data, false); + } + else + { + effective_data = calc_effective_disp(0, low_data, true); + } + } + fill_ea_string(&mem_data, (is_direct_address ? "" : EA_ENCODING_TXT[ea_table_value]), effective_disp); + printf("%s %s%s, %d\n", ARITHMETIC_OP_TXT[a_op], WORD_SIGNAL_TXT[is_wide], mem_data.string, effective_data); + fprintf(output, "%s %s%s, %d\n", ARITHMETIC_OP_TXT[a_op], WORD_SIGNAL_TXT[is_wide], mem_data.string, effective_data); + break; + case (MEM_8BIT_DISP): + extra_bytes += 1; + for (int i = 0; i < extra_bytes; i++) + { + fread(&(payload[i]), sizeof(byte), 1, bin.binary); + extra_bytes_read++; + } + + //Composing displacement and immediate values + low_disp = payload[0]; + effective_disp = calc_effective_disp(0, low_disp, true); + low_data = payload[1]; + if (is_wide && !is_sign) + { + high_data = payload[2]; + effective_data = calc_effective_disp(high_data, low_data, false); + } + else + { + effective_data = calc_effective_disp(0, low_disp, true); + } + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], effective_disp); + printf("%s %s%s, %d\n", ARITHMETIC_OP_TXT[a_op], WORD_SIGNAL_TXT[is_wide], mem_data.string, effective_data); + fprintf(output, "%s %s%s, %d\n", ARITHMETIC_OP_TXT[a_op], WORD_SIGNAL_TXT[is_wide], mem_data.string, effective_data); + break; + case (MEM_16BIT_DISP): + extra_bytes += 2; + for (int i = 0; i < extra_bytes; i++) + { + fread(&(payload[i]), sizeof(byte), 1, bin.binary); + extra_bytes_read++; + } + + //Composing displacement and immediate values + low_disp = payload[0]; + high_disp = payload[1]; + effective_disp = calc_effective_disp(high_disp, low_disp, false); + + low_data = payload[2]; + if (is_wide) + { + high_data = payload[3]; + effective_data = calc_effective_disp(high_data, low_data, false); + } + else + { + effective_data = calc_effective_disp(0, low_disp, true); + } + + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], effective_disp); + printf("%s %s%s, %d\n", ARITHMETIC_OP_TXT[a_op], WORD_SIGNAL_TXT[is_wide], mem_data.string, WORD_SIGNAL_TXT[is_wide], effective_data); + fprintf(output, "%s %s%s,%d\n", ARITHMETIC_OP_TXT[a_op], WORD_SIGNAL_TXT[is_wide], mem_data.string, effective_data); + break; + } + + return extra_bytes_read; +} + +int ASC_REGM_R_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read) +{ + const uint8_t wide_mask = 0b0000'0001; + const uint8_t dest_mask = 0b0000'0010; + const uint8_t mod_mask = 0b1100'0000; + const uint8_t regm_mask = 0b0011'1000; + const uint8_t op_mask = 0b0011'1000; + + unsigned char byte[1]; + uint8_t low_disp = 0; + uint8_t high_disp = 0; + uint16_t wide_disp = 0; + int16_t effective_disp = 0; + uint8_t extra_bytes_read = 0; + + uint8_t a_op = (byte1 & op_mask) >> 3; + + output_string mem_data; + mem_data.len = 0; + mem_data.string = calloc(18, sizeof(char)); //"[bp + di + 65535]\0" + + bool reg_is_dest = (byte1 & dest_mask); + uint8_t inst_mod = (byte2 & mod_mask) >> 6; + + //Number of chars disp value takes + int disp_len = 0; + + uint8_t reg_value = 0; + uint8_t ea_table_value = 0; + switch (inst_mod) + { + case (REG_NO_DISP): + //Since we're doing register mode/register to register, both reg and r/m are affected by the W bit + //if D=1, dest is retrieved from the reg field in byte2 and src from r/m + uint8_t dest_value = (reg_is_dest) ? ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8) + : (byte2 & (regm_mask >> 3)) + ((byte1 & wide_mask) * 8); + uint8_t src_value = (reg_is_dest) ? (byte2 & (regm_mask >> 3)) + ((byte1 & wide_mask) * 8) + : ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + printf("%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], REG_ENCODING_TXT[dest_value], REG_ENCODING_TXT[src_value]); + fprintf(output, "%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], REG_ENCODING_TXT[dest_value], REG_ENCODING_TXT[src_value]); + break; + case (MEM_8BIT_DISP): + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + low_disp = (uint8_t)byte[0]; + + reg_value = ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + ea_table_value = (byte2 & (regm_mask >> 3)); + effective_disp = calc_effective_disp(0, low_disp, true); + + //EA STRING GENERATION + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], effective_disp); + //END + + printf("%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + fprintf(output, "%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + break; + case (MEM_16BIT_DISP): + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + low_disp = (uint8_t)byte[0]; + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + high_disp = (uint8_t)byte[0]; + + //Composing wide displacement + effective_disp = calc_effective_disp(high_disp, low_disp, false); + + reg_value = ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + ea_table_value = (byte2 & (regm_mask >> 3)); + + //EA STRING GENERATION + fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], effective_disp); + //END + + printf("%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + fprintf(output, "%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + break; + case (MEM_NO_DISP): + //Checking if special case 110 applies + ea_table_value = (byte2 & (regm_mask >> 3)); + //If R/M equals 110, there actually is displacement to worry about + bool is_direct_address = (ea_table_value == 0b110); + if (is_direct_address) + { + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + low_disp = (uint8_t)byte[0]; + fread(byte, sizeof(byte), 1, bin.binary); + extra_bytes_read++; + high_disp = (uint8_t)byte[0]; + + //Composing wide displacement + effective_disp = calc_effective_disp(high_disp, low_disp, false); + } + + reg_value = ((byte2 & regm_mask) >> 3) + ((byte1 & wide_mask) * 8); + + //EA STRING GENERATION + fill_ea_string(&mem_data, (is_direct_address ? " " : EA_ENCODING_TXT[ea_table_value]), effective_disp); + //END + + printf("%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + fprintf(output, "%s %s, %s\n", ARITHMETIC_OP_TXT[a_op], (reg_is_dest ? REG_ENCODING_TXT[reg_value] + : mem_data.string) + , (reg_is_dest ? mem_data.string + : REG_ENCODING_TXT[reg_value])); + break; + } + return extra_bytes_read; +} + +int main(int argc, char** argv) +{ + if (argc != 2) return -1; + if (CHAR_BIT != 8) return -2; + + unsigned char byte[1]; + bin.binary = fopen(argv[1], "rb"); + fseek(bin.binary, 0, SEEK_END); + bin.size = ftell(bin.binary); + fseek(bin.binary, 0, SEEK_SET); + + output = fopen("output.asm", "w"); + fprintf(output, "%s\n\n", "bits 16"); + + for (int bytes_read = 0; bytes_read < bin.size; bytes_read++) + { + uint8_t inst_byte2 = 0; + fread(byte, sizeof(byte), 1, bin.binary); + uint8_t manip_inst = (uint8_t)byte[0]; + uint8_t inst = (uint8_t)byte[0]; + //First, we check for ASC. + manip_inst = (manip_inst >> 1); + if ((manip_inst & ASC_I_A_M) == ASC_I_A) + { + if (bytes_read >= bin.size) break; + fread(byte, sizeof(byte), 1, bin.binary); + bytes_read++; + inst_byte2 = (uint8_t)byte[0]; + bytes_read += ASC_I_A_parse(inst, inst_byte2, 0, 0); + continue; + } + manip_inst = (inst >> 2); + if ((manip_inst & ASC_REGM_R_M) == ASC_REGM_R) + { + if (bytes_read >= bin.size) break; + fread(byte, sizeof(byte), 1, bin.binary); + bytes_read++; + inst_byte2 = (uint8_t)byte[0]; + bytes_read += ASC_REGM_R_parse(inst, inst_byte2, 0, 0); + continue; + } + if (manip_inst == ASC_I_RM) + { + if (bytes_read >= bin.size) break; + fread(byte, sizeof(byte), 1, bin.binary); + bytes_read++; + inst_byte2 = (uint8_t)byte[0]; + bytes_read += ASC_I_RM_parse(inst, inst_byte2, 0, 0); + continue; + } + //Then, we're checking for all MOV except segment registers + manip_inst = (inst >> 1); + switch (manip_inst) + { + case MOV_M_T_A: + case MOV_A_T_M: + if (bytes_read >= bin.size) break; + fread(byte, sizeof(byte), 1, bin.binary); + bytes_read++; + inst_byte2 = (uint8_t)byte[0]; + bytes_read += MOV_MA_T_AM_parse(inst, inst_byte2, 0, 0, (manip_inst == MOV_M_T_A)); + continue; + case MOV_I_T_RM: + if (bytes_read >= bin.size) break; + fread(byte, sizeof(byte), 1, bin.binary); + bytes_read++; + inst_byte2 = (uint8_t)byte[0]; + bytes_read += MOV_I_T_RM_parse(inst, inst_byte2, 0, 0); + continue; + } + manip_inst = (manip_inst >> 1); + switch (manip_inst) + { + case MOV_RM_TF_R: + if (bytes_read >= bin.size) break; + fread(byte, sizeof(byte), 1, bin.binary); + bytes_read++; + inst_byte2 = (uint8_t)byte[0]; + bytes_read += MOV_RM_TF_R_parse(inst, inst_byte2, 0, 0); + continue; + } + manip_inst = (manip_inst >> 2); + if (manip_inst == MOV_I_T_R) + { + if (bytes_read >= bin.size) break; + fread(byte, sizeof(byte), 1, bin.binary); + bytes_read++; + inst_byte2 = (uint8_t)byte[0]; + bytes_read += MOV_I_T_R_parse(inst, inst_byte2, 0, 0); + continue; + } + } + + return 0; +} diff --git a/1-3/listing-41 b/1-3/listing-41 new file mode 100644 index 0000000000000000000000000000000000000000..b63415cb7d73ea205f0668b8dde807de9a667d44 GIT binary patch literal 76 zcmV-S0JHyt#sY)I0)xQ_fx+4JfCnOjg6IPs0N@4a0|ep(34`tegY5!?=?H)?B7-R% iE$9O*;w%Y+{sM#j0)zPofIlLGKH?G`J?H~G;yek