48 lines
1.4 KiB
C
48 lines
1.4 KiB
C
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
#define u32 uint32_t
|
|
#define u16 uint16_t
|
|
#define u8 uint8_t
|
|
|
|
const char *wide_reg_names[8] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
|
|
const char *non_wide_reg_names[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
|
|
|
|
const char *lookup_reg_name(u8 idx, bool wide) {
|
|
if (wide) {
|
|
return wide_reg_names[idx];
|
|
} else {
|
|
return non_wide_reg_names[idx];
|
|
}
|
|
}
|
|
|
|
void dissassemble(FILE *src, FILE *dst) {
|
|
fprintf(dst, "bits 16\n\n");
|
|
while (!feof(src)) {
|
|
u8 byte1 = fgetc(src);
|
|
u8 byte2 = fgetc(src);
|
|
|
|
// Register memory to/from register
|
|
if ((byte1 & 0b11111100) == 0b10001000) {
|
|
bool wide = byte1 & 0b1;
|
|
bool direction = (byte1 & 0b10) >> 1;
|
|
|
|
u8 mod = byte2 & 0b11000000;
|
|
u8 reg = (byte2 & 0b00111000) >> 3;
|
|
u8 rm = byte2 & 0b00000111;
|
|
if (mod == 0b11000000) {
|
|
const char *reg_name = lookup_reg_name(reg, wide);
|
|
const char *rm_name = lookup_reg_name(rm, wide);
|
|
if (direction) {
|
|
fprintf(dst, "mov %s, %s\n", reg_name, rm_name);
|
|
} else {
|
|
fprintf(dst, "mov %s, %s\n", rm_name, reg_name);
|
|
}
|
|
} else {
|
|
printf("ERROR: Unsupported mod '%d'", mod);
|
|
abort();
|
|
}
|
|
}
|
|
}
|
|
} |