1-2 challenge: I_T_RM implemented
This commit is contained in:
parent
15286389ad
commit
f984261641
2 changed files with 185 additions and 8 deletions
BIN
1-2/8086coded
BIN
1-2/8086coded
Binary file not shown.
191
1-2/decoder.c
191
1-2/decoder.c
|
|
@ -2,6 +2,9 @@
|
|||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue