summaryrefslogtreecommitdiff
path: root/archived/old_sim8086/8086disassembler.c
diff options
context:
space:
mode:
authorRaymaekers Luca <luca@spacehb.net>2025-08-23 16:22:13 +0200
committerRaymaekers Luca <luca@spacehb.net>2025-08-23 16:22:13 +0200
commitea20bd9b5bcff9db1d86d83188e1e899799f324b (patch)
tree615e2f00e385e93061524c9647b64010ba7df3dd /archived/old_sim8086/8086disassembler.c
checkpoint
Diffstat (limited to 'archived/old_sim8086/8086disassembler.c')
-rw-r--r--archived/old_sim8086/8086disassembler.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/archived/old_sim8086/8086disassembler.c b/archived/old_sim8086/8086disassembler.c
new file mode 100644
index 0000000..91e1a59
--- /dev/null
+++ b/archived/old_sim8086/8086disassembler.c
@@ -0,0 +1,157 @@
+/*
+ 8086 asm disassembler
+ For now this assumes that instructions are two bytes long.
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#define INSTRUCTION_MASK 0b11111100
+#define D_MASK (1 << 1)
+#define W_MASK 1
+#define REG_MASK 0b00111000
+#define MOD_MASK 0b00000111
+#define INSTRUCTION_MOV 0b10001000
+
+void print_reg(unsigned char reg, int wide_flag);
+
+int main(int argc, char **argv)
+{
+ FILE *file;
+ char *filename = argv[1];
+
+ if (argc < 2)
+ {
+ printf("No argument provided.\n");
+ return 1;
+ }
+
+ file = fopen(filename ,"rb");
+
+ if (file == NULL)
+ {
+ printf("File, %s not found.\n", filename);
+ return 1;
+ }
+
+ char file_byte;
+ unsigned char reg, mod, c;
+
+ /* flags */
+ int is_reg_destination = 0;
+ int is_wide_operation = 0;
+ char instruction[4];
+
+ /* print useful header */
+ printf("; %s disassembly:\n", filename);
+ printf("bits 16\n");
+
+
+ while ((file_byte = fgetc(file)) != EOF)
+ {
+ /* get the six first instruction bits */
+ c = file_byte & INSTRUCTION_MASK;
+ if (c == INSTRUCTION_MOV)
+ strcpy(instruction, "mov\0");
+ else
+ strcpy(instruction, "ERR\0");
+
+ /* check D bit */
+ /* NOTE: This shift could be defined to show that this is the D-mask */
+ c = file_byte & D_MASK;
+ is_reg_destination = c ? 1 : 0;
+
+ /* check W bit */
+ c = file_byte & 1;
+ is_wide_operation = c ? 1 : 0;
+
+ file_byte = fgetc(file);
+
+ /* get REG */
+ c = file_byte & REG_MASK;
+ reg = c >> 3;
+
+ /* get R/M */
+ c = file_byte & MOD_MASK;
+ mod = c;
+
+ /* print the decoded instructions */
+ printf("%s ", instruction);
+
+ /* print operands */
+ if (is_reg_destination)
+ print_reg(reg, is_wide_operation);
+ else
+ print_reg(mod, is_wide_operation);
+ printf(", ");
+ if (is_reg_destination)
+ print_reg(mod, is_wide_operation);
+ else
+ print_reg(reg, is_wide_operation);
+
+ printf("\n");
+ }
+
+ fclose(file);
+
+ return 0;
+}
+
+void print_reg(unsigned char reg, int wide_flag)
+{
+ switch (reg)
+ {
+ case 0b000:
+ if (wide_flag)
+ printf("ax");
+ else
+ printf("al");
+ break;
+ case 0b001:
+ if (wide_flag)
+ printf("cx");
+ else
+ printf("cl");
+ break;
+ case 0b010:
+ if (wide_flag)
+ printf("dx");
+ else
+ printf("dl");
+ break;
+ case 0b011:
+ if (wide_flag)
+ printf("bx");
+ else
+ printf("bl");
+ break;
+ case 0b100:
+ if (wide_flag)
+ printf("sp");
+ else
+ printf("ah");
+ break;
+ case 0b101:
+ if (wide_flag)
+ printf("bp");
+ else
+ printf("ch");
+ break;
+ case 0b110:
+ if (wide_flag)
+ printf("si");
+ else
+ printf("dh");
+ break;
+ case 0b111:
+ if (wide_flag)
+ printf("di");
+ else
+ printf("dh");
+ break;
+ default:
+ /* unknown register */
+ printf("ER");
+ break;
+ }
+} \ No newline at end of file