solutions
- the structure of registers
// TODO: Re-organize the `CPU_state' structure to match the register
// encoding scheme in i386 instruction format. For example, if we
// access cpu.gpr[3]._16, we will get the `bx' register; if we access
// cpu.gpr[1]._8[1], we will get the 'ch' register. Hint: Use `union'.
// For more details about the register encoding scheme, see i386 manual.
//
typedef struct {
union {
union {
uint32_t _32;
uint16_t _16;
uint8_t _8[2];
} gpr[8];
/* Do NOT change the order of the GPRs' definitions. */
struct {
uint32_t eax, ecx, edx, ebx, esp, ebp, esi, edi;
};
};
swaddr_t eip;
} CPU_state;
static int cmd_step(char *args) {
cpu_exec(1);
return 0;
}
static void dump_regs() {
int i;
for(i = R_EAX; i <= R_EDI; i ++) {
printf("%s: 0x%08x\n", regsl[i], cpu.gpr[i]._32);
}
printf("eip: 0x%08x\n", cpu.eip);
}
static int cmd_info(char *args) {
switch (*args) {
case 'r': dump_regs(); return 0;
default: return 1;
}
}
static int cmd_dump_mem(char *args) {
unsigned int addr, len, i;
sscanf(args, "%d 0x%x", &len, &addr);
printf("dump memory start addr: 0x%08x len: %d\n", addr, len);
for (i = 0; i < len; ++i) {
if (!(i & 0xf)) printf("\n0x%08x: ", addr + i * 16);
printf("0x%02x ", *(unsigned char *)hwa_to_va(addr + i));
}
printf("\n");
return 0;
}
static struct {
char *name;
char *description;
int (*handler) (char *);
} cmd_table [] = {
{ "help", "Display informations about all supported commands", cmd_help },
{ "c", "Continue the execution of the program", cmd_c },
{ "q", "Exit NEMU", cmd_q },
/* TODO: Add more commands */
{ "s", "Single step", cmd_step},
{ "info", "dump informations with option: r(registers)", cmd_info},
{ "x", "dump memory: x length addr", cmd_dump_mem},
};