1
0

complete homework 2

This commit is contained in:
Rokas Puzonas 2023-04-09 20:46:23 +03:00
parent 7110ff6df1
commit 8e4f7419a1

View File

@ -1,15 +1,31 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#define u32 uint32_t
#define u16 uint16_t
#define u8 uint8_t
#define todo(...) fprintf(stderr, "TODO(%s:%d): ", __FILE__, __LINE__); fprintf(stderr, __VA_ARGS__); abort()
#define dbg(...) printf("; "); printf(__VA_ARGS__); printf("\n")
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 *mod_lookup_names[8] = {
"bx + si",
"bx + di",
"bp + si",
"bp + di",
"si",
"di",
"bp",
"bx"
};
const char *lookup_reg_name(u8 idx, bool wide) {
assert(0 <= idx && idx <= 7);
if (wide) {
return wide_reg_names[idx];
} else {
@ -19,30 +35,57 @@ const char *lookup_reg_name(u8 idx, bool wide) {
void dissassemble(FILE *src, FILE *dst) {
fprintf(dst, "bits 16\n\n");
while (!feof(src)) {
while (true) {
u8 byte1 = fgetc(src);
u8 byte2 = fgetc(src);
if (feof(src)) break;
// Register memory to/from register
if ((byte1 & 0b11111100) == 0b10001000) {
u8 byte2 = fgetc(src);
bool wide = byte1 & 0b1;
bool direction = (byte1 & 0b10) >> 1;
u8 mod = byte2 & 0b11000000;
u8 reg = (byte2 & 0b00111000) >> 3;
u8 rm = byte2 & 0b00000111;
const char *reg_name = lookup_reg_name(reg, wide);
char rm_name[24] = { 0 };
if (mod == 0b11000000) { // Mod = 0b11
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);
}
strcpy(rm_name, lookup_reg_name(rm, wide));
} else if (mod == 0b10000000) { // Mod = 0b10
u16 immidiate = fgetc(src) | (fgetc(src) << 8);
snprintf(rm_name, sizeof(rm_name), "[%s + %d]", mod_lookup_names[rm], immidiate);
} else if (mod == 0b01000000) { // Mod = 0b01
u8 immidiate = fgetc(src);
snprintf(rm_name, sizeof(rm_name), "[%s + %d]", mod_lookup_names[rm], immidiate);
} else if (mod == 0b00000000) { // Mod = 0b00
if (rm == 0b110) { // Direct address
todo("direct address");
} else {
snprintf(rm_name, sizeof(rm_name), "[%s]", mod_lookup_names[rm]);
}
}
if (direction) {
fprintf(dst, "mov %s, %s\n", reg_name, rm_name);
} else {
fprintf(dst, "mov %s, %s\n", rm_name, reg_name);
}
// Immediate to register
} else if ((byte1 & 0b11110000) == 0b10110000) {
bool wide = (byte1 & 0b1000) >> 3;
u8 reg = byte1 & 0b111;
u16 immidiate;
if (wide) {
immidiate = fgetc(src) | (fgetc(src) << 8);
} else {
immidiate = fgetc(src);
}
fprintf(dst, "mov %s, %d\n", lookup_reg_name(reg, wide), immidiate);
} else {
todo("unhandled byte %d", byte1);
}
}
}