void debug_disasm(ui32 ins) { instruction_t *instr = disassemble_instruction(ins); puts("==========================="); puts(instr->disassembled_str); switch (instr->type) { default: case NO_OPERANDS: break; case REGISTER_REGISTER: pprint("oper1", registers[instr->operand1.reg]); pprint("oper2", registers[instr->operand2.reg]); break; case REGISTER_IMMEDIATE: pprint("oper1", registers[instr->operand1.reg]); pprint("oper2", instr->operand2.imm); break; case REGISTER_NO_IMMEDIATE: pprint("oper1", registers[instr->operand1.imm]); break; case IMMEDIATE_NO_REGISTER: pprint("oper1", instr->operand1.imm); break; } free_instruction(&instr); }
static void dis_model_refresh_rows (DisModel *model) { int row_num, got_bytes = 0; DisModelRowData row; guint16 address = model->address; GtkTreePath *path; GtkTreeIter iter; path = gtk_tree_path_new_first (); for (row_num = 0; row_num < DIS_MODEL_ROW_COUNT; row_num++) { if (model->electron == NULL) { row.address = 0; row.num_bytes = 0; row.mnemonic[0] = '\0'; row.operands[0] = '\0'; row.current = FALSE; } else { while (got_bytes < DISASSEMBLE_MAX_BYTES) { row.bytes[got_bytes] = electron_read_from_location (model->electron->data, address + got_bytes); got_bytes++; } row.address = address; row.num_bytes = disassemble_instruction (address, row.bytes, row.mnemonic, row.operands); row.current = model->electron->data->cpu.pc == address ? TRUE : FALSE; } /* Only fire the changed signal if the row is actually different */ if (row.address != model->rows[row_num].address || row.num_bytes != model->rows[row_num].num_bytes || memcmp (row.bytes, model->rows[row_num].bytes, row.num_bytes) || row.current != model->rows[row_num].current) { model->rows[row_num] = row; gtk_tree_path_get_indices (path)[0] = row_num; iter.user_data = GINT_TO_POINTER (row_num); iter.stamp = model->iter_stamp; gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter); } memmove (row.bytes, row.bytes + row.num_bytes, got_bytes = DISASSEMBLE_MAX_BYTES - row.num_bytes); address += row.num_bytes; } gtk_tree_path_free (path); }
static int test_disassemble_instruction_x86(void){ struct disassembler *dis; uint8_t inst[8]; char line[512]; size_t inst_size; dis = new_disassembler(0); FAIL_IF(dis == NULL); inst[0] = 0x90; disassemble_instruction(dis, inst, sizeof(inst), 0x100, line, sizeof(line), &inst_size); FAIL_IF(inst_size != 1); FAIL_IF(strncmp(line, "nop", 3) != 0); free_disassembler(dis); return 0; }
/** * TODO: Turn this into lib functionality to be used in both a seperate disass * binary, and with a flag in the emulator itself. */ int main(int argc, char *argv[]) { // TODO: Use the GNU C args parsing lib if(argc == 1) { printf("Usage todo, RTFM\n"); return 1; } else if(argc > 2) { printf("Only the first argument is used!\n"); // Bah } uint32_t* in_word = malloc(sizeof(uint32_t)); FILE* fp = fopen(argv[1], "rb"); fseek(fp, 0, SEEK_END); int num_bytes = ftell(fp); fseek(fp, 0, SEEK_SET); printf("Disassembling %s (%i bytes):\n\n", argv[1], num_bytes); unsigned char buff[1024]; unsigned int address = 0; while(fread(in_word, sizeof(uint32_t), 1, fp) != 0) { struct Instruction* instruction = malloc(sizeof(struct Instruction)); decode_instruction(in_word, instruction); disassemble_instruction(instruction, (char *)buff); printf("0x%x: %s\n", address, buff); address++; } int res = fclose(fp); if(res != 0) { printf("Error closing %s", argv[1]); } free(in_word); return 0; }