99 lines
2.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
enum Instruction
{
INST_MOV = 0b10001000
};
enum Register
{
REG_AL_AX = 0b000,
REG_CL_CX = 0b001,
REG_DL_DX = 0b010,
REG_BL_BX = 0b011,
REG_AH_SP = 0b100,
REG_CH_BP = 0b101,
REG_DH_SI = 0b110,
REG_BH_DI = 0b111,
};
#define REG_AX "ax"
#define REG_CX "cx"
#define REG_BX "bx"
enum Mode
{
MODE_MEM_NOD = 0b00,
MODE_MEM_08D = 0b01,
MODE_MEM_16D = 0b10,
MODE_REGMODE = 0b11,
};
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 byte = buf[i];
switch (byte & 0b11111100)
{
case INST_MOV:
char high_byte = buf[i+1];
// char w = byte & 0b00000001;
// char d = byte & 0b00000010;
char mod = (high_byte & 0b11000000) >> 6;
char reg = (high_byte & 0b00111000) >> 3;
char r_m = (high_byte & 0b00000111);
printf("mov ");
if (mod == MODE_REGMODE)
{
char *dest_reg_name = NULL;
switch (r_m)
{
case REG_CL_CX:
dest_reg_name = REG_CX;
break;
case REG_BL_BX:
dest_reg_name = REG_BX;
break;
}
printf("%s, ", dest_reg_name);
char *src_reg_name = NULL;
switch (reg)
{
case REG_CL_CX:
src_reg_name = REG_CX;
break;
case REG_BL_BX:
src_reg_name = REG_BX;
break;
}
printf("%s", src_reg_name);
}
break;
default:
perror("Unrecognized Instruction\n");
}
}
printf("\n");
}