diff --git a/arch/x86/x86_decode.cpp b/arch/x86/x86_decode.cpp index f4a1a76..14bfdaa 100644 --- a/arch/x86/x86_decode.cpp +++ b/arch/x86/x86_decode.cpp @@ -179,10 +179,10 @@ static const uint32_t decode_table[256] = { /*[0x9D]*/ INSTR_POPF | ADDMODE_IMPLIED, /*[0x9E]*/ INSTR_SAHF | ADDMODE_IMPLIED, /*[0x9F]*/ INSTR_LAHF | ADDMODE_IMPLIED, - /*[0xA0]*/ INSTR_MOV | ADDMODE_MEM_ACC | WIDTH_BYTE, /* load */ - /*[0xA1]*/ INSTR_MOV | ADDMODE_MEM_ACC | WIDTH_FULL, /* load */ - /*[0xA2]*/ INSTR_MOV | ADDMODE_ACC_MEM | WIDTH_BYTE, /* store */ - /*[0xA3]*/ INSTR_MOV | ADDMODE_ACC_MEM | WIDTH_FULL, /* store */ + /*[0xA0]*/ INSTR_MOV | ADDMODE_MOFFSET_ACC | WIDTH_BYTE, /* load */ + /*[0xA1]*/ INSTR_MOV | ADDMODE_MOFFSET_ACC | WIDTH_FULL, /* load */ + /*[0xA2]*/ INSTR_MOV | ADDMODE_ACC_MOFFSET | WIDTH_BYTE, /* store */ + /*[0xA3]*/ INSTR_MOV | ADDMODE_ACC_MOFFSET | WIDTH_FULL, /* store */ /*[0xA4]*/ INSTR_MOVSB | ADDMODE_IMPLIED | WIDTH_BYTE, /*[0xA5]*/ INSTR_MOVSW | ADDMODE_IMPLIED | WIDTH_FULL, /*[0xA6]*/ INSTR_CMPSB | ADDMODE_IMPLIED | WIDTH_BYTE, @@ -318,6 +318,7 @@ decode_dst_operand(struct x86_instr *instr) operand->type = OP_REG; operand->reg = 0; /* AL/AX */ break; + case DST_MOFFSET: case DST_MEM: operand->type = OP_MEM; operand->disp = instr->disp; @@ -372,6 +373,7 @@ decode_src_operand(struct x86_instr *instr) operand->type = OP_REG; operand->reg = 0; /* AL/AX */ break; + case SRC_MOFFSET: case SRC_MEM: operand->type = OP_MEM; operand->disp = instr->disp; @@ -470,6 +472,21 @@ decode_rel(struct x86_instr *instr, uint8_t* RAM, addr_t *pc) } } +static void +decode_moffset(struct x86_instr *instr, uint8_t* RAM, addr_t *pc) +{ + switch (instr->flags & WIDTH_MASK) { + case WIDTH_FULL: + instr->disp = read_u16(RAM, pc); + instr->nr_bytes += 2; + break; + case WIDTH_BYTE: + instr->disp = read_u8(RAM, pc); + instr->nr_bytes += 1; + break; + } +} + static void decode_disp(struct x86_instr *instr, uint8_t* RAM, addr_t *pc) { @@ -588,6 +605,9 @@ arch_8086_decode_instr(struct x86_instr *instr, uint8_t* RAM, addr_t pc) if (instr->flags & MEM_DISP_MASK) decode_disp(instr, RAM, &pc); + if (instr->flags & MOFFSET_MASK) + decode_moffset(instr, RAM, &pc); + if (instr->flags & IMM_MASK) decode_imm(instr, RAM, &pc); diff --git a/arch/x86/x86_decode.h b/arch/x86/x86_decode.h index 4189cc3..03a224d 100644 --- a/arch/x86/x86_decode.h +++ b/arch/x86/x86_decode.h @@ -67,22 +67,26 @@ enum x86_instr_flags { SRC_SEG_REG = (1U << 17), SRC_ACC = (1U << 18), SRC_MEM = (1U << 19), - SRC_MEM_DISP_BYTE = (1U << 20), - SRC_MEM_DISP_FULL = (1U << 21), - SRC_MASK = SRC_NONE|IMM_MASK|REL_MASK|SRC_REG|SRC_SEG_REG|SRC_ACC|SRC_MEM|SRC_MEM_DISP_BYTE|SRC_MEM_DISP_FULL, + SRC_MOFFSET = (1U << 20), + SRC_MEM_DISP_BYTE = (1U << 21), + SRC_MEM_DISP_FULL = (1U << 22), + SRC_MASK = SRC_NONE|IMM_MASK|REL_MASK|SRC_REG|SRC_SEG_REG|SRC_ACC|SRC_MEM|SRC_MOFFSET|SRC_MEM_DISP_BYTE|SRC_MEM_DISP_FULL, /* Destination operand */ - DST_NONE = (1U << 22), - DST_REG = (1U << 23), - DST_ACC = (1U << 24), /* AL/AX */ - DST_MEM = (1U << 25), - DST_MEM_DISP_BYTE = (1U << 26), /* 8 bits */ - DST_MEM_DISP_FULL = (1U << 27), /* 16 bits or 32 bits */ - DST_MASK = DST_NONE|DST_REG|DST_ACC|DST_MEM|DST_MEM_DISP_BYTE|DST_MEM_DISP_FULL, + DST_NONE = (1U << 23), + DST_REG = (1U << 24), + DST_ACC = (1U << 25), /* AL/AX */ + DST_MEM = (1U << 26), + DST_MOFFSET = (1U << 27), + DST_MEM_DISP_BYTE = (1U << 28), /* 8 bits */ + DST_MEM_DISP_FULL = (1U << 29), /* 16 bits or 32 bits */ + DST_MASK = DST_NONE|DST_REG|DST_ACC|DST_MOFFSET|DST_MEM|DST_MEM_DISP_BYTE|DST_MEM_DISP_FULL, MEM_DISP_MASK = SRC_MEM|SRC_MEM_DISP_BYTE|SRC_MEM_DISP_FULL|DST_MEM|DST_MEM_DISP_BYTE|DST_MEM_DISP_FULL, - GROUP_2 = (1U << 28), + MOFFSET_MASK = SRC_MOFFSET|DST_MOFFSET, + + GROUP_2 = (1U << 30), GROUP_MASK = GROUP_2, }; @@ -91,14 +95,14 @@ enum x86_instr_flags { * Addressing modes. */ enum x86_addmode { - ADDMODE_ACC_MEM = SRC_ACC|DST_MEM|DIR_REVERSED, /* AL/AX -> memory */ + ADDMODE_ACC_MOFFSET = SRC_ACC|DST_MOFFSET, /* AL/AX -> moffset */ ADDMODE_ACC_REG = SRC_ACC|DST_REG, /* AL/AX -> reg */ ADDMODE_IMM = SRC_IMM|DST_NONE, /* immediate operand */ ADDMODE_IMM8_RM = SRC_IMM8|MOD_RM|DIR_REVERSED, /* immediate -> register/memory */ ADDMODE_IMM_ACC = SRC_IMM|DST_ACC, /* immediate -> AL/AX */ ADDMODE_IMM_REG = SRC_IMM|DST_REG, /* immediate -> register */ ADDMODE_IMPLIED = SRC_NONE|DST_NONE, /* no operands */ - ADDMODE_MEM_ACC = SRC_ACC|DST_MEM, /* memory -> AL/AX */ + ADDMODE_MOFFSET_ACC = SRC_MOFFSET|DST_ACC, /* moffset -> AL/AX */ ADDMODE_REG = SRC_REG|DST_NONE, /* register */ ADDMODE_SEG_REG = SRC_SEG_REG|DST_NONE, /* segment register */ ADDMODE_REG_RM = SRC_REG|MOD_RM|DIR_REVERSED, /* register -> register/memory */