complete homework 2
This commit is contained in:
parent
7110ff6df1
commit
8e4f7419a1
61
src/asm.c
61
src/asm.c
@ -1,15 +1,31 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#define u32 uint32_t
|
#define u32 uint32_t
|
||||||
#define u16 uint16_t
|
#define u16 uint16_t
|
||||||
#define u8 uint8_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 *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 *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) {
|
const char *lookup_reg_name(u8 idx, bool wide) {
|
||||||
|
assert(0 <= idx && idx <= 7);
|
||||||
if (wide) {
|
if (wide) {
|
||||||
return wide_reg_names[idx];
|
return wide_reg_names[idx];
|
||||||
} else {
|
} else {
|
||||||
@ -19,30 +35,57 @@ const char *lookup_reg_name(u8 idx, bool wide) {
|
|||||||
|
|
||||||
void dissassemble(FILE *src, FILE *dst) {
|
void dissassemble(FILE *src, FILE *dst) {
|
||||||
fprintf(dst, "bits 16\n\n");
|
fprintf(dst, "bits 16\n\n");
|
||||||
while (!feof(src)) {
|
while (true) {
|
||||||
u8 byte1 = fgetc(src);
|
u8 byte1 = fgetc(src);
|
||||||
u8 byte2 = fgetc(src);
|
if (feof(src)) break;
|
||||||
|
|
||||||
// Register memory to/from register
|
// Register memory to/from register
|
||||||
if ((byte1 & 0b11111100) == 0b10001000) {
|
if ((byte1 & 0b11111100) == 0b10001000) {
|
||||||
|
u8 byte2 = fgetc(src);
|
||||||
bool wide = byte1 & 0b1;
|
bool wide = byte1 & 0b1;
|
||||||
bool direction = (byte1 & 0b10) >> 1;
|
bool direction = (byte1 & 0b10) >> 1;
|
||||||
|
|
||||||
u8 mod = byte2 & 0b11000000;
|
u8 mod = byte2 & 0b11000000;
|
||||||
u8 reg = (byte2 & 0b00111000) >> 3;
|
u8 reg = (byte2 & 0b00111000) >> 3;
|
||||||
u8 rm = byte2 & 0b00000111;
|
u8 rm = byte2 & 0b00000111;
|
||||||
|
const char *reg_name = lookup_reg_name(reg, wide);
|
||||||
|
char rm_name[24] = { 0 };
|
||||||
if (mod == 0b11000000) { // Mod = 0b11
|
if (mod == 0b11000000) { // Mod = 0b11
|
||||||
const char *reg_name = lookup_reg_name(reg, wide);
|
strcpy(rm_name, lookup_reg_name(rm, 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 if (mod == 0b10000000) { // Mod = 0b10
|
} 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
|
} 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
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user