diff options
| author | Raymaekers Luca <luca@spacehb.net> | 2025-08-23 16:22:13 +0200 |
|---|---|---|
| committer | Raymaekers Luca <luca@spacehb.net> | 2025-08-23 16:22:13 +0200 |
| commit | ea20bd9b5bcff9db1d86d83188e1e899799f324b (patch) | |
| tree | 615e2f00e385e93061524c9647b64010ba7df3dd /archived/old_sim8086/8086disassembler.c | |
checkpoint
Diffstat (limited to 'archived/old_sim8086/8086disassembler.c')
| -rw-r--r-- | archived/old_sim8086/8086disassembler.c | 157 |
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 |
