90 lines
2.3 KiB
C
90 lines
2.3 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "lib.h"
|
|
|
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
|
|
|
enum Instruction
|
|
{
|
|
INST_MOV = 0b10001000
|
|
};
|
|
|
|
enum Mode
|
|
{
|
|
MODE_MEM_NOD = 0b00,
|
|
MODE_MEM_08D = 0b01,
|
|
MODE_MEM_16D = 0b10,
|
|
MODE_REGMODE = 0b11,
|
|
};
|
|
|
|
typedef struct Register
|
|
{
|
|
char code;
|
|
char *fullname;
|
|
char *bytename;
|
|
union {
|
|
struct {
|
|
char low;
|
|
char high;
|
|
};
|
|
u16 full;
|
|
} value;
|
|
} Register;
|
|
|
|
Register registers[8] = {
|
|
{.code = 0b000, .fullname = "ax", .bytename = "al" },
|
|
{.code = 0b001, .fullname = "cx", .bytename = "cl" },
|
|
{.code = 0b010, .fullname = "dx", .bytename = "dl" },
|
|
{.code = 0b011, .fullname = "bx", .bytename = "bl" },
|
|
{.code = 0b100, .fullname = "sp", .bytename = "ah" },
|
|
{.code = 0b101, .fullname = "bp", .bytename = "ch" },
|
|
{.code = 0b110, .fullname = "si", .bytename = "dh" },
|
|
{.code = 0b111, .fullname = "di", .bytename = "bh" },
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc < 2)
|
|
{
|
|
printf("Usage: Please provide assembled instructions as input\n");
|
|
exit(0);
|
|
}
|
|
unsigned char buf[256];
|
|
FILE *f = fopen(argv[1], "r");
|
|
if (!f)
|
|
{
|
|
perror("fopen\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
size_t bytes_read = fread(buf, sizeof(*buf), ARRAY_SIZE(buf), f);
|
|
|
|
printf("; Decoded 8086 Assembly Instructions\n\n");
|
|
printf("bits 16\n\n");
|
|
for (int i = 0; i < (int)bytes_read / 2; i += 2)
|
|
{
|
|
char low_byte = buf[i];
|
|
char high_byte = buf[i+1];
|
|
// char w = byte & 0b00000001;
|
|
char d = low_byte & 0b00000010;
|
|
char mod = (high_byte & 0b11000000) >> 6;
|
|
char reg = (high_byte & 0b00111000) >> 3;
|
|
char r_m = (high_byte & 0b00000111);
|
|
size_t reg_idx = reg;
|
|
size_t r_m_idx = r_m;
|
|
Register src_reg = d == 0 ? registers[reg_idx] : registers[r_m_idx];
|
|
Register dst_reg = d == 0 ? registers[r_m_idx] : registers[reg_idx];
|
|
switch (low_byte & 0b11111100)
|
|
{
|
|
case INST_MOV:
|
|
if (mod == MODE_REGMODE)
|
|
{
|
|
printf("mov %s, %s", dst_reg.fullname, src_reg.fullname);
|
|
}
|
|
break;
|
|
default:
|
|
perror("Unrecognized Instruction\n");
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|