NEMU PA1

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;

  • debug utilities
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},

};

你可能感兴趣的:(NEMU PA1)