diff --git a/1-2/8086coded b/1-2/8086coded index 751d795..e681639 100755 Binary files a/1-2/8086coded and b/1-2/8086coded differ diff --git a/1-2/decoder.c b/1-2/decoder.c index 670a509..821731d 100644 --- a/1-2/decoder.c +++ b/1-2/decoder.c @@ -2,6 +2,9 @@ #include #include #include +#include + +//TODO: Pass file struct and currently read bytes via param enum DT_INSTRUCTIONS { @@ -18,17 +21,20 @@ enum MOV_REGISTER_MODE { MEM_NO_DISP = 0b00, MEM_8BIT_DISP = 0b01, - MEM_16BIT_DISP = 0b010, + 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"}; + "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"}; + "si", "di", "bp", "bx" }; + +#define WORD_SIGNAL_LEN 6 +char WORD_SIGNAL_TXT[0b10][WORD_SIGNAL_LEN] = { "byte ", "word " }; /* enum REG_ENCODING */ /* { */ @@ -133,6 +139,167 @@ int MOV_I_T_R_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes 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) + { + memcpy(str->string, " + ", 3); + str->string += 3; + str->len += 3; + } + 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 MOV_REGISTER_MODE 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 + 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; +} int MOV_RM_TF_R_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read) { @@ -305,19 +472,29 @@ int main(int argc, char** argv) 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]; //We're checking for all MOV except segment registers manip_inst = (manip_inst >> 1); - if (manip_inst == MOV_M_T_A || manip_inst == MOV_A_T_M) - { + 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++; - uint8_t inst_byte2 = (uint8_t)byte[0]; + 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); if (manip_inst == MOV_RM_TF_R) @@ -325,7 +502,7 @@ int main(int argc, char** argv) if (bytes_read >= bin.size) break; fread(byte, sizeof(byte), 1, bin.binary); bytes_read++; - uint8_t inst_byte2 = (uint8_t)byte[0]; + inst_byte2 = (uint8_t)byte[0]; bytes_read += MOV_RM_TF_R_parse(inst, inst_byte2, 0, 0); continue; } @@ -335,7 +512,7 @@ int main(int argc, char** argv) if (bytes_read >= bin.size) break; fread(byte, sizeof(byte), 1, bin.binary); bytes_read++; - uint8_t inst_byte2 = (uint8_t)byte[0]; + inst_byte2 = (uint8_t)byte[0]; bytes_read += MOV_I_T_R_parse(inst, inst_byte2, 0, 0); continue; }