MOV inst conditional branching cleaned up considerably, cause god it was ugly
This commit is contained in:
parent
7f094799e9
commit
094733ee70
119
decode.c
119
decode.c
@ -89,6 +89,16 @@ char* get_eac_registers(char rm)
|
||||
return reg_name;
|
||||
}
|
||||
|
||||
static inline char *reg_name(Register reg, char wide)
|
||||
{
|
||||
return wide == 1 ? reg.fullname : reg.bytename;
|
||||
}
|
||||
|
||||
static inline i16 get_data(unsigned char *buf, char wide)
|
||||
{
|
||||
return wide == 1 ? (i16)buf[1] << 8 | buf[0] : buf[0];
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
@ -103,6 +113,7 @@ int main(int argc, char** argv)
|
||||
perror("fopen\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
size_t bytes_read;
|
||||
|
||||
printf("; Decoded 8086 Assembly Instructions\n\n");
|
||||
@ -119,69 +130,34 @@ int main(int argc, char** argv)
|
||||
bytes_read = fread(buf, sizeof(char), 1, f);
|
||||
char next_byte = buf[0];
|
||||
char w = inst & 0b00000001;
|
||||
char d = inst & 0b00000010;
|
||||
char d = (inst & 0b00000010) >> 1;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
Register src_reg = d == 0 ? registers[reg_idx] : registers[rm_idx];
|
||||
Register dst_reg = d == 0 ? registers[rm_idx] : registers[reg_idx];
|
||||
printf("mov %s, %s ;0", reg_name(dst_reg, w), reg_name(src_reg, w));
|
||||
}
|
||||
else
|
||||
{
|
||||
// char* src_name = w == 1 ? src_reg.fullname : src_reg.bytename;
|
||||
char *dst_name;
|
||||
if (d)
|
||||
// This is a trick because mod == 1 and mod == 2 will displace one and two bytes
|
||||
// respectively but mod == 3 wraps to 0 since it doesn't displace
|
||||
int bytes_to_read = mod % 3;
|
||||
bytes_read = fread(buf, sizeof(char), bytes_to_read, f);
|
||||
char* eac_name = get_eac_registers(rm);
|
||||
char disp_buf[16] = {'\0'};
|
||||
if (bytes_to_read > 0)
|
||||
{
|
||||
dst_name = w == 1 ? dst_reg.fullname : dst_reg.bytename;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_name = w == 1 ? src_reg.fullname : src_reg.bytename;
|
||||
}
|
||||
char* src_name = get_eac_registers(rm);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
i16 disp = get_data(buf, bytes_to_read - 1);
|
||||
if (disp > 0) sprintf(disp_buf, " %s %d", disp >= 0 ? "+" : "-", abs(disp));
|
||||
}
|
||||
Register reg = registers[reg_idx];
|
||||
if (d) printf("mov %s, [%s%s] ;1", reg_name(reg, w), eac_name, disp_buf);
|
||||
else printf("mov [%s%s], %s ;2", eac_name, disp_buf, reg_name(reg, w));
|
||||
}
|
||||
}
|
||||
// Immediate to register/memory
|
||||
@ -193,34 +169,41 @@ int main(int argc, char** argv)
|
||||
char rm = (buf[0] & 0b00000111);
|
||||
int bytes_to_read = 1;
|
||||
bytes_to_read += w == 0 ? 0 : 1;
|
||||
// This is a trick because mod == 1 and mod == 2 will displace one and two bytes
|
||||
// respectively but mod == 3 wraps to 0 since it doesn't displace
|
||||
// Same trick from earlier, see comment
|
||||
bytes_to_read += mod % 3;
|
||||
bytes_read = fread(buf, sizeof(char), bytes_to_read, f);
|
||||
char *eac_name = get_eac_registers(rm);
|
||||
char *data_ptr = (char*)buf + (char)bytes_to_read - (w == 0 ? 1 : 2);
|
||||
i16 data = w == 0 ? data_ptr[0] : (i16)data_ptr[1] << 8 | data_ptr[0];
|
||||
char *word = w == 0 ? "byte" : "word";
|
||||
char *disp = mod == 1 || mod == 2 ? sprintf();
|
||||
printf("mov [%s], %s %d w %d mod %d rm %d", eac_name, word, data, w, mod, rm);
|
||||
char disp_str[16];
|
||||
if (mod > 0 && mod < 3)
|
||||
{
|
||||
if (mod == 1)
|
||||
{
|
||||
sprintf(disp_str, " + %d", buf[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
i16 disp = (i16)buf[1] << 8 | buf[0];
|
||||
sprintf(disp_str, " + %d", disp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
disp_str[0] = '\0';
|
||||
}
|
||||
|
||||
printf("mov [%s%s], %s %d ;w %d mod %d rm %d", eac_name, disp_str, word, data, w, mod, rm);
|
||||
}
|
||||
// Immediate to register
|
||||
else if ((inst & ~0xF) == (char)0b10110000)
|
||||
{
|
||||
char w = inst & 0b00001000;
|
||||
char w = (inst & 0b00001000) >> 3;
|
||||
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]);
|
||||
}
|
||||
char bytes_to_read = w == 1 ? 2 : 1;
|
||||
bytes_read = fread(buf, sizeof(char), bytes_to_read, f);
|
||||
printf("mov %s, %hd ; Immediate to register", reg_name(reg, w), get_data(buf, w));
|
||||
}
|
||||
// Memory to accumulator
|
||||
else if ((inst & ~0x1) == (char)0b10100000)
|
||||
|
Loading…
x
Reference in New Issue
Block a user