#include "include/aliases.h" #include "include/reg_access.h" #include "include/sim86_lib.h" #include #include #include void decode_operand(instruction_operand operand); void mov_to_register(const register_access ®, const instruction_operand &source); int main(int argc, char *argv[]) { if (argc < 2) { printf("Usage: sim86 BINARY_FILE\n"); return 1; } const char *filename = argv[1]; printf("Filename: %s\n", filename); FILE *fp = fopen(filename, "rb"); if (!fp) { printf("Failed to open file %s\n", filename); } fseek(fp, 0, SEEK_END); u32 size = ftell(fp); fseek(fp, 0, SEEK_SET); u8 buffer[size + 1]; memset((void *)buffer, 0, size + 1); fread((void *)buffer, sizeof(u8), size, fp); fclose(fp); instruction_table table; Sim86_Get8086InstructionTable(&table); u32 offset = 0; bool accessed_registers[REGISTER_COUNT] = {false}; while (offset < size) { instruction decoded; Sim86_Decode8086Instruction(size - offset, buffer + offset, &decoded); if (decoded.Op) { offset += decoded.Size; if (decoded.Op == Op_mov) { instruction_operand dest = decoded.Operands[0]; instruction_operand source = decoded.Operands[1]; if (dest.Type == Operand_Register) { mov_to_register(dest.Register, source); accessed_registers[dest.Register.Index] = true; } } } } for (u32 i = 0; i < REGISTER_COUNT; ++i) { if (accessed_registers[i]) { register_access reg = {i, 0, 2}; u16 value = get_register(reg); printf("%s: 0x%04x (%d)\n", get_register_name(reg), value, value); } } return 0; } void decode_operand(instruction_operand operand) { switch (operand.Type) { case Operand_Register: printf("Register operand: %d, %d, %d\n", operand.Register.Index, operand.Register.Offset, operand.Register.Count); break; case Operand_Memory: // printf("Memory operand\n"); break; case Operand_Immediate: // printf("Immediate operand\n"); break; default: break; } } void mov_to_register(const register_access ®, const instruction_operand &source) { switch (source.Type) { case Operand_Immediate: set_register(reg, source.Immediate.Value); break; case Operand_Register: set_register(reg, get_register(source.Register)); break; default: break; } }