summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog36
-rw-r--r--src/arch/artificial.c2
-rw-r--r--src/arch/instruction.c48
-rw-r--r--src/arch/instruction.h6
-rw-r--r--src/arch/jvm/operand.c2
-rw-r--r--src/arch/x86/instruction.c392
-rw-r--r--src/arch/x86/instruction.h13
-rw-r--r--src/arch/x86/op_and.c110
-rw-r--r--src/arch/x86/op_cmp.c36
-rw-r--r--src/arch/x86/op_int.c2
-rw-r--r--src/arch/x86/op_jump.c72
-rw-r--r--src/arch/x86/op_mul.c36
-rw-r--r--src/arch/x86/opcodes.h21
-rw-r--r--src/arch/x86/operand.c381
-rw-r--r--src/arch/x86/operand.h13
-rw-r--r--src/arch/x86/processor.c35
16 files changed, 694 insertions, 511 deletions
diff --git a/ChangeLog b/ChangeLog
index 1d4ecd5..a22419d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+09-10-07 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/arch/artificial.c:
+ Replace a call to g_arch_instruction_attach_one_operand() by a call
+ to g_arch_instruction_attach_extra_operand().
+
+ * src/arch/instruction.c:
+ * src/arch/instruction.h:
+ Remove the g_arch_instruction_attach_(one|two)_operand[s]() functions.
+ One can use g_arch_instruction_attach_extra_operand() instead.
+
+ * src/arch/jvm/operand.c:
+ Replace a call to g_arch_instruction_attach_one_operand() by a call
+ to g_arch_instruction_attach_extra_operand().
+
+ * src/arch/x86/instruction.c:
+ * src/arch/x86/instruction.h:
+ * src/arch/x86/op_and.c:
+ * src/arch/x86/op_cmp.c:
+ * src/arch/x86/opcodes.h:
+ Support extra x86 opcodes.
+
+ * src/arch/x86/operand.c:
+ * src/arch/x86/operand.h:
+ Create a function to load n operands. Remove the older ones allowing to
+ load one or two operands. Add comments to fix later endianness.
+
+ * src/arch/x86/op_int.c:
+ Replace a call to g_arch_instruction_attach_one_operand() by a call
+ to g_arch_instruction_attach_extra_operand().
+
+ * src/arch/x86/op_jump.c:
+ * src/arch/x86/op_mul.c:
+ * src/arch/x86/processor.c:
+ Support extra x86 opcodes.
+
09-10-06 Cyrille Bagard <nocbos@gmail.com>
* src/arch/immediate.c:
diff --git a/src/arch/artificial.c b/src/arch/artificial.c
index a1fa56e..16e95bc 100644
--- a/src/arch/artificial.c
+++ b/src/arch/artificial.c
@@ -139,7 +139,7 @@ GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, off_t *pos,
g_arch_processor_get_endianness(proc));
if (operand == NULL) goto gdinfd_error;
- g_arch_instruction_attach_one_operand(result, operand);
+ g_arch_instruction_attach_extra_operand(result, operand);
return result;
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 8bc317b..16e5c81 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -196,54 +196,6 @@ void g_arch_instruction_get_location(GArchInstruction *instr, off_t *offset, off
* Paramètres : instr = instance à mettre à jour. *
* opererand = instruction à venir associer. *
* *
-* Description : Attache un seul opérande à un instruction. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_arch_instruction_attach_one_operand(GArchInstruction *instr, GArchOperand *operand)
-{
- instr->operands = (GArchOperand **)calloc(1, sizeof(GArchOperand *));
- instr->operands_count = 1;
-
- instr->operands[0] = operand;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instance à mettre à jour. *
-* operand1 = première instruction à venir associer. *
-* operand2 = seconde instruction à venir associer. *
-* *
-* Description : Attache deux opérandes à un instruction. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_arch_instruction_attach_two_operands(GArchInstruction *instr, GArchOperand *operand1, GArchOperand *operand2)
-{
- instr->operands = (GArchOperand **)calloc(2, sizeof(GArchOperand *));
- instr->operands_count = 2;
-
- instr->operands[0] = operand1;
- instr->operands[1] = operand2;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : instr = instance à mettre à jour. *
-* opererand = instruction à venir associer. *
-* *
* Description : Attache un opérande supplémentaire à une instruction. *
* *
* Retour : - *
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index accaed6..0c51b93 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -70,12 +70,6 @@ void g_arch_instruction_set_location(GArchInstruction *, off_t, off_t, vmpa_t);
/* Fournit la localisation d'une instruction. */
void g_arch_instruction_get_location(GArchInstruction *, off_t *, off_t *, vmpa_t *);
-/* Attache un seul opérande à une instruction. */
-void g_arch_instruction_attach_one_operand(GArchInstruction *, GArchOperand *);
-
-/* Attache deux opérandes à une instruction. */
-void g_arch_instruction_attach_two_operands(GArchInstruction *, GArchOperand *, GArchOperand *);
-
/* Attache un opérande supplémentaire à une instruction. */
void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *);
diff --git a/src/arch/jvm/operand.c b/src/arch/jvm/operand.c
index 429516a..a485a2b 100644
--- a/src/arch/jvm/operand.c
+++ b/src/arch/jvm/operand.c
@@ -324,7 +324,7 @@ bool jvm_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos
if (op == NULL) return false;
- g_arch_instruction_attach_one_operand(instr, op);
+ g_arch_instruction_attach_extra_operand(instr, op);
return true;
diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c
index c8d31a0..72143ee 100644
--- a/src/arch/x86/instruction.c
+++ b/src/arch/x86/instruction.c
@@ -80,262 +80,274 @@ typedef struct _x86_instruction
static x86_instruction _instructions[XOP_COUNT] = {
- [XOP_ADD_RM8_R8] = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE },
- [XOP_ADD_RM1632_R1632] = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ADD_R8_RM8] = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE },
- [XOP_ADD_R1632_RM1632] = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ADD_AL_IMM8] = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE },
- [XOP_ADD_E_AX_IMM1632] = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADD_RM8_R8] = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE },
+ [XOP_ADD_RM1632_R1632] = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADD_R8_RM8] = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE },
+ [XOP_ADD_R1632_RM1632] = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADD_AL_IMM8] = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE },
+ [XOP_ADD_E_AX_IMM1632] = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE },
+ [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE },
- [XOP_OR_RM8_R8] = { false, 0x08, IDX_TO_EXT(-1), "or", XPX_NONE },
- [XOP_OR_RM1632_R1632] = { false, 0x09, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE },
- [XOP_OR_R1632_RM1632] = { false, 0x0b, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_OR_AL_IMM8] = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE },
+ [XOP_OR_RM8_R8] = { false, 0x08, IDX_TO_EXT(-1), "or", XPX_NONE },
+ [XOP_OR_RM1632_R1632] = { false, 0x09, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE },
+ [XOP_OR_R1632_RM1632] = { false, 0x0b, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_OR_AL_IMM8] = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE },
- [XOP_JE_REL1632] = { false, 0x84, IDX_TO_EXT(-1), "je", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_JNE_REL1632] = { false, 0x85, IDX_TO_EXT(-1), "jne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JE_REL1632] = { false, 0x84, IDX_TO_EXT(-1), "je", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JNE_REL1632] = { false, 0x85, IDX_TO_EXT(-1), "jne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JBE_REL1632] = { false, 0x86, IDX_TO_EXT(-1), "jbe", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JA_REL1632] = { false, 0x87, IDX_TO_EXT(-1), "ja", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_JA_REL1632] = { false, 0x87, IDX_TO_EXT(-1), "ja", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
-
- [XOP_JGE_REL1632] = { false, 0x8d, IDX_TO_EXT(-1), "jge", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_JLE_REL1632] = { false, 0x8e, IDX_TO_EXT(-1), "jle", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
-
-
- [XOP_SETE_RM8] = { false, 0x94, IDX_TO_EXT(-1), "sete", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SETNE_RM8] = { false, 0x95, IDX_TO_EXT(-1), "setne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
-
-
- [XOP_MOVZX_R1632_RM8] = { false, 0xb6, IDX_TO_EXT(-1), "movzx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOVSX_R1632_RM8] = { false, 0xbe, IDX_TO_EXT(-1), "movsx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JGE_REL1632] = { false, 0x8d, IDX_TO_EXT(-1), "jge", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JLE_REL1632] = { false, 0x8e, IDX_TO_EXT(-1), "jle", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JG_REL1632] = { false, 0x8f, IDX_TO_EXT(-1), "jg", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ADC_RM8_R8] = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE },
-
- [XOP_AND_RM8_R8] = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE },
-
- [XOP_SUB_RM1632_R1632] = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE },
-
- [XOP_SUB_R8_RM8] = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE },
- [XOP_SUB_AL_IMM8] = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE },
-
- [XOP_SUB_E_AX_IMM1632] = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE },
-
+ [XOP_SETE_RM8] = { false, 0x94, IDX_TO_EXT(-1), "sete", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SETNE_RM8] = { false, 0x95, IDX_TO_EXT(-1), "setne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XOR_RM8_R8] = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE},
- [XOP_XOR_RM1632_R1632] = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XOR_R8_RM8] = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE},
- [XOP_XOR_R1632_RM1632] = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XOR_AL_IMM8] = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE },
- [XOP_XOR_E_AX_IMM1632] = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOVZX_R1632_RM8] = { false, 0xb6, IDX_TO_EXT(-1), "movzx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOVSX_R1632_RM8] = { false, 0xbe, IDX_TO_EXT(-1), "movsx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADC_RM8_R8] = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE },
+ [XOP_AND_RM8_R8] = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE },
+ [XOP_AND_RM1632_R1632] = { false, 0x21, IDX_TO_EXT(-1), "and", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_CMP_RM1632_R1632] = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_AX] = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_CX] = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_DX] = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_BX] = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_SP] = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_BP] = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_SI] = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INC_E_DI] = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_AX] = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_CX] = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_DX] = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_BX] = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_SP] = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_BP] = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_SI] = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_E_DI] = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_AX] = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_CX] = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_DX] = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_BX] = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_SP] = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_BP] = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_SI] = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_E_DI] = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_AX] = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_CX] = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_DX] = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_BX] = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_SP] = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_BP] = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_SI] = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_POP_E_DI] = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_AND_AL_IMM8] = { false, 0x24, IDX_TO_EXT(-1), "and", XPX_NONE },
+ [XOP_AND_E_AX_IMM1632] = { false, 0x25, IDX_TO_EXT(-1), "and", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_IMM1632] = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SUB_RM1632_R1632] = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SUB_R8_RM8] = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE },
+ [XOP_SUB_AL_IMM8] = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE },
- [XOP_IMUL_RM1632_IMM8] = { false, 0x6b, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SUB_E_AX_IMM1632] = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_JO_REL8] = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE },
- [XOP_JNO_REL8] = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE },
- [XOP_JB_REL8] = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE },
- [XOP_JNB_REL8] = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE },
- [XOP_JE_REL8] = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE },
- [XOP_JNE_REL8] = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE },
- [XOP_JNA_REL8] = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE },
- [XOP_JA_REL8] = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE },
- [XOP_JS_REL8] = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE },
- [XOP_JNS_REL8] = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE },
- [XOP_JP_REL8] = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE },
- [XOP_JNP_REL8] = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE },
- [XOP_JL_REL8] = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE },
- [XOP_JNL_REL8] = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE },
- [XOP_JNG_REL8] = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE },
- [XOP_JG_REL8] = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE },
- [XOP_ADD_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE },
- [XOP_OR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE },
- [XOP_ADC_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE },
- [XOP_SBB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE },
- [XOP_AND_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE },
- [XOP_SUB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE },
- [XOP_XOR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE },
- [XOP_CMP_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE },
- [XOP_ADD_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_OR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ADC_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SBB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_AND_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SUB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XOR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_CMP_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_RM8_R8] = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE},
+ [XOP_XOR_RM1632_R1632] = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_R8_RM8] = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE},
+ [XOP_XOR_R1632_RM1632] = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_AL_IMM8] = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE },
+ [XOP_XOR_E_AX_IMM1632] = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ADD_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_OR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ADC_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SBB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_AND_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SUB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XOR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_CMP_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_TEST_RM8_R8] = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE },
- [XOP_TEST_RM1632_R1632] = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_RM8_R8] = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_RM1632_R1632] = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_CMP_RM1632_R1632] = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_CMP_R1632_RM1632] = { false, 0x3b, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_R1632_RM1632] = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_AX] = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_CX] = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_DX] = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_BX] = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_SP] = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_BP] = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_SI] = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_DI] = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_AX] = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_CX] = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_DX] = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_BX] = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_SP] = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_BP] = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_SI] = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_DI] = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_AX] = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_CX] = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_DX] = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_BX] = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_SP] = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_BP] = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_SI] = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_DI] = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_AX] = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_CX] = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_DX] = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_BX] = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_SP] = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_BP] = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_SI] = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_DI] = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_LEA_R1632_M] = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_IMM1632] = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_IMUL_R1632_RM1632_IMM1632] = { false, 0x69, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_NOP] = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE },
- [XOP_XCHG_R1632_E_AX] = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XCHG_R1632_E_CX] = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XCHG_R1632_E_DX] = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XCHG_R1632_E_BX] = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XCHG_R1632_E_SP] = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XCHG_R1632_E_BP] = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XCHG_R1632_E_SI] = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_XCHG_R1632_E_DI] = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_IMUL_RM1632_IMM8] = { false, 0x6b, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_AL_MOFFS8] = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_E_AX_MOFFS1632] = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_MOFFS8_AL] = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_MOFFS1632_E_AX] = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JO_REL8] = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE },
+ [XOP_JNO_REL8] = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE },
+ [XOP_JB_REL8] = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE },
+ [XOP_JNB_REL8] = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE },
+ [XOP_JE_REL8] = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE },
+ [XOP_JNE_REL8] = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE },
+ [XOP_JNA_REL8] = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE },
+ [XOP_JA_REL8] = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE },
+ [XOP_JS_REL8] = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE },
+ [XOP_JNS_REL8] = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE },
+ [XOP_JP_REL8] = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE },
+ [XOP_JNP_REL8] = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE },
+ [XOP_JL_REL8] = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE },
+ [XOP_JNL_REL8] = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE },
+ [XOP_JNG_REL8] = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE },
+ [XOP_JG_REL8] = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE },
+ [XOP_ADD_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE },
+ [XOP_OR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE },
+ [XOP_ADC_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE },
+ [XOP_SBB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE },
+ [XOP_AND_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE },
+ [XOP_SUB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE },
+ [XOP_XOR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE },
+ [XOP_CMP_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE },
+ [XOP_ADD_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_OR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADC_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SBB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_AND_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SUB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_CMP_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_TEST_AL_IMM8] = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE },
- [XOP_TEST_E_AX_IMM1632] = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADD_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_OR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADC_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SBB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_AND_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SUB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_CMP_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SCAS_AL_M8] = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE },
+ [XOP_TEST_RM8_R8] = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE },
+ [XOP_TEST_RM1632_R1632] = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_AL_IMM8] = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_CL_IMM8] = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_DL_IMM8] = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_BL_IMM8] = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_AH_IMM8] = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_CH_IMM8] = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_DH_IMM8] = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_BH_IMM8] = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE },
- [XOP_MOV_E_AX_IMM1632] = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_E_CX_IMM1632] = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_E_DX_IMM1632] = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_E_BX_IMM1632] = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_E_SP_IMM1632] = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_E_BP_IMM1632] = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_E_SI_IMM1632] = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_E_DI_IMM1632] = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_RM8_R8] = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_RM1632_R1632] = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_R1632_RM1632] = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ROL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_ROR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_RCL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_RCR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SHL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SHR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SAL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_SAR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_LEA_R1632_M] = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_RET] = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE },
+ [XOP_NOP] = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE },
+ [XOP_XCHG_R1632_E_AX] = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_CX] = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_DX] = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_BX] = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_SP] = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_BP] = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_SI] = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_DI] = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_MOV_RM8_IMM8] = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE },
- [XOP_MOV_RM1632_IMM1632] = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_AL_MOFFS8] = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_E_AX_MOFFS1632] = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_MOFFS8_AL] = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_MOFFS1632_E_AX] = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_LEAVE] = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE },
+ [XOP_TEST_AL_IMM8] = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE },
+ [XOP_TEST_E_AX_IMM1632] = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_INT_3] = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE },
- [XOP_INT] = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE },
+ [XOP_SCAS_AL_M8] = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE },
- [XOP_SHL_RM1632_CL] = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_AL_IMM8] = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_CL_IMM8] = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_DL_IMM8] = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_BL_IMM8] = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_AH_IMM8] = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_CH_IMM8] = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_DH_IMM8] = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_BH_IMM8] = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_E_AX_IMM1632] = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_CX_IMM1632] = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_DX_IMM1632] = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_BX_IMM1632] = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_SP_IMM1632] = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_BP_IMM1632] = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_SI_IMM1632] = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_DI_IMM1632] = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_CALL_REL1632] = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_JMP_REL1632] = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_JMP_REL8] = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE },
- [XOP_HLT] = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE },
+ [XOP_ROL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ROR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_RCL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_RCR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SHL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SHR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SAL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SAR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_TEST_RM8_IMM8] = { false, 0xf6, IDX_TO_EXT(0), "test", XPX_NONE },
- [XOP_TEST_RM8_IMM8_BIS] = { false, 0xf6, IDX_TO_EXT(1), "test", XPX_NONE },
- [XOP_NOT_RM8] = { false, 0xf6, IDX_TO_EXT(2), "not", XPX_NONE },
- [XOP_TEST_RM1632_IMM1632] = { false, 0xf7, IDX_TO_EXT(0), "test", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_TEST_RM1632_IMM1632_BIS] = { false, 0xf7, IDX_TO_EXT(1), "test", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_NOT_RM1632] = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_RET] = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE },
- [XOP_IMUL_RM1632] = { false, 0xf7, IDX_TO_EXT(5), "imul", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_RM8_IMM8] = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE },
+ [XOP_MOV_RM1632_IMM1632] = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_CLD] = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE },
- [XOP_INC_RM8] = { false, 0xfe, IDX_TO_EXT(0), "inc", XPX_NONE },
- [XOP_DEC_RM8] = { false, 0xfe, IDX_TO_EXT(1), "dec", XPX_NONE },
- [XOP_INC_RM1632] = { false, 0xff, IDX_TO_EXT(0), "inc", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_DEC_RM1632] = { false, 0xff, IDX_TO_EXT(1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_CALL_RM1632] = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_JMP_RM1632] = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE },
- [XOP_PUSH_RM1632] = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE }
+ [XOP_LEAVE] = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE },
+
+
+ [XOP_INT_3] = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE },
+ [XOP_INT] = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE },
+
+
+ [XOP_SHL_RM1632_CL] = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_CALL_REL1632] = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JMP_REL1632] = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE },
+
+ [XOP_JMP_REL8] = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE },
+
+ [XOP_HLT] = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE },
+
+ [XOP_TEST_RM8_IMM8] = { false, 0xf6, IDX_TO_EXT(0), "test", XPX_NONE },
+ [XOP_TEST_RM8_IMM8_BIS] = { false, 0xf6, IDX_TO_EXT(1), "test", XPX_NONE },
+ [XOP_NOT_RM8] = { false, 0xf6, IDX_TO_EXT(2), "not", XPX_NONE },
+
+ [XOP_TEST_RM1632_IMM1632] = { false, 0xf7, IDX_TO_EXT(0), "test", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_TEST_RM1632_IMM1632_BIS] = { false, 0xf7, IDX_TO_EXT(1), "test", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_NOT_RM1632] = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE },
+
+ [XOP_IMUL_RM1632] = { false, 0xf7, IDX_TO_EXT(5), "imul", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_CLD] = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE },
+
+
+ [XOP_INC_RM8] = { false, 0xfe, IDX_TO_EXT(0), "inc", XPX_NONE },
+ [XOP_DEC_RM8] = { false, 0xfe, IDX_TO_EXT(1), "dec", XPX_NONE },
+ [XOP_INC_RM1632] = { false, 0xff, IDX_TO_EXT(0), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_RM1632] = { false, 0xff, IDX_TO_EXT(1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_CALL_RM1632] = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JMP_RM1632] = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_RM1632] = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE }
};
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index ad50834..de5f124 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -50,11 +50,12 @@ typedef enum _X86Opcodes
XOP_JE_REL1632, /* je ([0x66] 0x0f 0x84) */
XOP_JNE_REL1632, /* jne ([0x66] 0x0f 0x85) */
-
+ XOP_JBE_REL1632, /* jbe ([0x66] 0x0f 0x86) */
XOP_JA_REL1632, /* jne ([0x66] 0x0f 0x87) */
XOP_JGE_REL1632, /* jge ([0x66] 0x0f 0x8d) */
XOP_JLE_REL1632, /* jle ([0x66] 0x0f 0x8e) */
+ XOP_JG_REL1632, /* jle ([0x66] 0x0f 0x8f) */
XOP_SETE_RM8, /* sete ([0x66] 0x0f 0x94) */
XOP_SETNE_RM8, /* setne ([0x66] 0x0f 0x95) */
@@ -65,6 +66,10 @@ typedef enum _X86Opcodes
XOP_ADC_RM8_R8, /* adc (0x10) */
XOP_AND_RM8_R8, /* and (0x20) */
+ XOP_AND_RM1632_R1632, /* and ([0x66] 0x21) */
+
+ XOP_AND_AL_IMM8, /* and (0x24) */
+ XOP_AND_E_AX_IMM1632, /* and ([0x66] 0x25) */
XOP_SUB_RM1632_R1632, /* sub ([0x66] 0x29) */
@@ -81,8 +86,11 @@ typedef enum _X86Opcodes
XOP_XOR_AL_IMM8, /* xor (0x34) */
XOP_XOR_E_AX_IMM1632, /* xor ([0x66] 0x35) */
-
XOP_CMP_RM1632_R1632, /* cmp ([0x66] 0x39) */
+
+ XOP_CMP_R1632_RM1632, /* cmp ([0x66] 0x3b) */
+
+
XOP_INC_E_AX, /* inc ([0x66] 0x40) */
XOP_INC_E_CX, /* inc ([0x66] 0x41) */
XOP_INC_E_DX, /* inc ([0x66] 0x42) */
@@ -118,6 +126,7 @@ typedef enum _X86Opcodes
XOP_PUSH_IMM1632, /* push ([0x66] 0x68) */
+ XOP_IMUL_R1632_RM1632_IMM1632, /* imul ([0x66] 0x69) */
XOP_IMUL_RM1632_IMM8, /* imul ([0x66] 0x6b) */
diff --git a/src/arch/x86/op_and.c b/src/arch/x86/op_and.c
index c923441..d59c8f0 100644
--- a/src/arch/x86/op_and.c
+++ b/src/arch/x86/op_and.c
@@ -38,6 +38,75 @@
* addr = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
+* Description : Décode une instruction de type 'and al, ...' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_and_al_imm8(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_x86_instruction_new(XOP_AND_AL_IMM8);
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_IMM8))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'and [e]ax, ...' (16/32 bits).*
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_and_e_ax_imm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = g_x86_instruction_new(XOP_AND_E_AX_IMM1632);
+
+ oprsize = g_x86_processor_get_operand_size(proc, prefix);
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_E_AX, X86_OTP_IMM1632, oprsize))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
* Description : Décode une instruction de type 'and' (8 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
@@ -65,6 +134,11 @@ GArchInstruction *x86_read_instr_and_rm8_imm8(const bin_t *data, off_t *pos, off
/******************************************************************************
* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
* *
* Description : Décode une instruction de type 'and' (8 bits). *
* *
@@ -161,3 +235,39 @@ GArchInstruction *x86_read_instr_and_rm1632_imm1632(const bin_t *data, off_t *po
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'and' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_and_rm1632_r1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = g_x86_instruction_new(XOP_AND_RM1632_R1632);
+
+ oprsize = g_x86_processor_get_operand_size(proc, prefix);
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_cmp.c b/src/arch/x86/op_cmp.c
index 709054b..5dfa20d 100644
--- a/src/arch/x86/op_cmp.c
+++ b/src/arch/x86/op_cmp.c
@@ -38,6 +38,42 @@
* addr = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
+* Description : Décode une instruction de type 'cmp' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_cmp_r1632_rm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = g_x86_instruction_new(XOP_CMP_R1632_RM1632);
+
+ oprsize = g_x86_processor_get_operand_size(proc, prefix);
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
* Description : Décode une instruction de type 'cmp' (8 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
diff --git a/src/arch/x86/op_int.c b/src/arch/x86/op_int.c
index cbeda87..eef2c1c 100644
--- a/src/arch/x86/op_int.c
+++ b/src/arch/x86/op_int.c
@@ -55,7 +55,7 @@ GArchInstruction *x86_read_instr_int_3(const bin_t *data, off_t *pos, off_t len,
result = g_x86_instruction_new(XOP_INT_3);
three = g_imm_operand_new_from_value(AOS_8_BITS, 3);
- g_arch_instruction_attach_one_operand(result, three);
+ g_arch_instruction_attach_extra_operand(result, three);
return result;
diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c
index 1f7db24..be8d305 100644
--- a/src/arch/x86/op_jump.c
+++ b/src/arch/x86/op_jump.c
@@ -140,6 +140,42 @@ GArchInstruction *x86_read_instr_jb_rel8(const bin_t *data, off_t *pos, off_t le
* addr = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
+* Description : Décode une instruction de type 'je' (saut 16/32b si inf.). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_jbe_rel1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = g_x86_instruction_new(XOP_JBE_REL1632);
+
+ oprsize = g_x86_processor_get_operand_size(proc, prefix);
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, addr))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
* Description : Décode une instruction de type 'je' (saut 8b si égal). *
* *
* Retour : Instruction mise en place ou NULL. *
@@ -242,6 +278,42 @@ GArchInstruction *x86_read_instr_jg_rel8(const bin_t *data, off_t *pos, off_t le
* addr = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
+* Description : Décode une instruction de type 'jg' (saut 16/32b si sup.). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_jg_rel1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = g_x86_instruction_new(XOP_JG_REL1632);
+
+ oprsize = g_x86_processor_get_operand_size(proc, prefix);
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, addr))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
* Description : Décode une instruction de type 'jge' (saut 16/32b si sup.). *
* *
* Retour : Instruction mise en place ou NULL. *
diff --git a/src/arch/x86/op_mul.c b/src/arch/x86/op_mul.c
index f1ed641..2f29929 100644
--- a/src/arch/x86/op_mul.c
+++ b/src/arch/x86/op_mul.c
@@ -46,6 +46,42 @@
* *
******************************************************************************/
+GArchInstruction *x86_read_instr_imul_r1632_rm1632_imm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+
+ result = g_x86_instruction_new(XOP_IMUL_R1632_RM1632_IMM1632);
+
+ oprsize = g_x86_processor_get_operand_size(proc, prefix);
+
+ if (!x86_read_three_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* offset = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'imul' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
GArchInstruction *x86_read_instr_imul_rm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
{
GArchInstruction *result; /* Instruction à retourner */
diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h
index 5317415..e45b107 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -69,6 +69,12 @@ GArchInstruction *x86_read_instr_add_rm1632_imm1632(const bin_t *, off_t *, off_
/* Décode une instruction de type 'add' (16 ou 32 bits). */
GArchInstruction *x86_read_instr_add_rm1632_r1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+/* Décode une instruction de type 'and al, ...' (8 bits). */
+GArchInstruction *x86_read_instr_and_al_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
+/* Décode une instruction de type 'and [e]ax, ...' (16/32 bits). */
+GArchInstruction *x86_read_instr_and_e_ax_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
/* Décode une instruction de type 'and' (8 bits). */
GArchInstruction *x86_read_instr_and_rm8_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
@@ -81,6 +87,9 @@ GArchInstruction *x86_read_instr_and_rm1632_imm8(const bin_t *, off_t *, off_t,
/* Décode une instruction de type 'and' (16 ou 32 bits). */
GArchInstruction *x86_read_instr_and_rm1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+/* Décode une instruction de type 'and' (16 ou 32 bits). */
+GArchInstruction *x86_read_instr_and_rm1632_r1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
/* Décode une instruction de type 'call'. */
GArchInstruction *x86_read_instr_call_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
@@ -90,6 +99,9 @@ GArchInstruction *x86_read_instr_call_rm1632(const bin_t *, off_t *, off_t, vmpa
/* Décode une instruction de type 'cld'. */
GArchInstruction *x86_read_instr_cld(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+/* Décode une instruction de type 'cmp' (16 ou 32 bits). */
+GArchInstruction *x86_read_instr_cmp_r1632_rm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
/* Décode une instruction de type 'cmp' (8 bits). */
GArchInstruction *x86_read_instr_cmp_rm8_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
@@ -115,6 +127,9 @@ GArchInstruction *x86_read_instr_dec_rm1632(const bin_t *, off_t *, off_t, vmpa_
GArchInstruction *x86_read_instr_hlt(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
/* Décode une instruction de type 'imul' (16 ou 32 bits). */
+GArchInstruction *x86_read_instr_imul_r1632_rm1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
+/* Décode une instruction de type 'imul' (16 ou 32 bits). */
GArchInstruction *x86_read_instr_imul_rm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
/* Décode une instruction de type 'imul' (16 ou 32 bits). */
@@ -144,6 +159,9 @@ GArchInstruction *x86_read_instr_ja_rel1632(const bin_t *, off_t *, off_t, vmpa_
/* Décode une instruction de type 'jb' (saut 8b si inférieur). */
GArchInstruction *x86_read_instr_jb_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+/* Décode une instruction de type 'je' (saut 16/32b si inf.). */
+GArchInstruction *x86_read_instr_jbe_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
/* Décode une instruction de type 'je' (saut 8b si égal). */
GArchInstruction *x86_read_instr_je_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
@@ -153,6 +171,9 @@ GArchInstruction *x86_read_instr_je_rel1632(const bin_t *, off_t *, off_t, vmpa_
/* Décode une instruction de type 'jg' (saut 8b si supérieur). */
GArchInstruction *x86_read_instr_jg_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+/* Décode une instruction de type 'jg' (saut 16/32b si sup.). */
+GArchInstruction *x86_read_instr_jg_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
/* Décode une instruction de type 'jge' (saut 16/32b si sup.). */
GArchInstruction *x86_read_instr_jge_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index eb6f5f3..d0e923f 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -512,7 +512,7 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,
if (g_x86_register_is_base_pointer(reg) && mod == 0x00)
{
/* FIXME *///free_x86_register(reg);
- return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE);
+ return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/);
}
result = g_object_new(G_TYPE_X86_MOD_RM_OPERAND, NULL);
@@ -552,19 +552,19 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,
/* FIXME *///free_x86_register(result->base);
result->base = NULL;
- result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE);
+ result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);
if (result->displacement == NULL) goto gxmron_error;
}
break;
case 0x40:
- result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE);
+ result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */);
if (result->displacement == NULL) goto gxmron_error;
break;
case 0x80:
- result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE);
+ result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */);
if (result->displacement == NULL) goto gxmron_error;
break;
@@ -805,15 +805,15 @@ GArchOperand *g_x86_relative_operand_new(const bin_t *data, off_t *pos, off_t le
switch (size)
{
case AOS_8_BITS_UNSIGNED:
- read_s8(&val8, data, pos, len, SRE_LITTLE);
+ read_s8(&val8, data, pos, len, SRE_LITTLE /* FIXME */);
address = base + (*pos - init_pos) + val8;
break;
case AOS_16_BITS_UNSIGNED:
- read_s16(&val16, data, pos, len, SRE_LITTLE);
+ read_s16(&val16, data, pos, len, SRE_LITTLE /* FIXME */);
address = base + (*pos - init_pos) + val16;
break;
case AOS_32_BITS_UNSIGNED:
- read_s32(&val32, data, pos, len, SRE_LITTLE);
+ read_s32(&val32, data, pos, len, SRE_LITTLE /* FIXME */);
address = base + (*pos - init_pos) + val32;
break;
default:
@@ -945,7 +945,7 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,
result = NULL;
- offset = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE);
+ offset = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);
if (offset != NULL)
{
@@ -997,10 +997,10 @@ static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *operan
* data = flux de données à analyser. *
* pos = position courante dans ce flux. [OUT] *
* len = taille totale des données à analyser. *
-* type = type de l'opérande. *
+* count = quantité d'opérandes à lire. *
* ... = éventuelle(s) information(s) complémentaire(s). *
* *
-* Description : Procède à la lecture d'un opérande donné. *
+* Description : Procède à la lecture de trois opérandes donnés. *
* *
* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
* *
@@ -1008,135 +1008,39 @@ static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *operan
* *
******************************************************************************/
-bool x86_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, X86OperandType type, ...)
+bool _x86_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, unsigned int count, ...)
{
+ bool result; /* Bilan à retourner */
va_list ap; /* Liste des compléments */
+ X86OperandType types[MAX_OPERANDS]; /* Type des opérandes */
+ unsigned int i; /* Boucle de parcours */
+ bool op1_first; /* Position de l'opérande #1 */
+ bool op2_first; /* Position de l'opérande #2 */
AsmOperandSize oprsize; /* Taille des opérandes */
+ off_t op_pos[MAX_OPERANDS]; /* Position après lecture */
vmpa_t offset; /* Adresse courante */
bin_t base; /* Indice du premier registre */
GArchOperand *op; /* Opérande unique décodé */
- va_start(ap, type);
-
- /* Lecture du premier opérande */
-
- switch (type)
- {
- case X86_OTP_IMM8:
- op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, len, SRE_LITTLE);
- break;
-
- case X86_OTP_IMM1632:
- oprsize = va_arg(ap, AsmOperandSize);
- op = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, pos, len, SRE_LITTLE);
- break;
-
- case X86_OTP_REL8:
- offset = va_arg(ap, vmpa_t);
- op = g_x86_relative_operand_new(data, pos, len, AOS_8_BITS, offset + 1);
- break;
-
- case X86_OTP_REL1632:
- oprsize = va_arg(ap, AsmOperandSize);
- offset = va_arg(ap, vmpa_t);
- op = g_x86_relative_operand_new(data, pos, len, oprsize, offset + 1);
- break;
-
- case X86_OTP_R8:
- op = g_x86_register_operand_new_from_mod_rm(data, pos, len, AOS_8_BITS, true);
- break;
-
- case X86_OTP_R1632:
- oprsize = va_arg(ap, AsmOperandSize);
- op = g_x86_register_operand_new_from_mod_rm(data, pos, len, oprsize, true);
- break;
-
- case X86_OTP_OP_R8:
- base = (bin_t)va_arg(ap, int);
- op = g_x86_register_operand_new_from_opcode(data, pos, len, AOS_8_BITS, base);
- break;
-
- case X86_OTP_OP_R1632:
- oprsize = va_arg(ap, AsmOperandSize);
- base = (bin_t)va_arg(ap, int);
- op = g_x86_register_operand_new_from_opcode(data, pos, len, oprsize, base);
- break;
-
- case X86_OTP_RM8:
- op = g_x86_mod_rm_operand_new(data, pos, len, AOS_8_BITS);
- break;
-
- case X86_OTP_RM1632:
- oprsize = va_arg(ap, AsmOperandSize);
- op = g_x86_mod_rm_operand_new(data, pos, len, oprsize);
- break;
-
- case X86_OTP_CL:
- op = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS);
- break;
-
- case X86_OTP_AL:
- op = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS);
- break;
-
- case X86_OTP_E_AX:
- oprsize = va_arg(ap, AsmOperandSize);
- op = g_x86_register_operand_new_from_index(0x00, oprsize);
- break;
-
- }
-
- va_end(ap);
-
- if (op == NULL) return false;
-
- g_arch_instruction_attach_one_operand(instr, op);
-
- return true;
-
-}
+ if (count > MAX_OPERANDS) return false;
+ result = true;
-/******************************************************************************
-* *
-* Paramètres : instr = instruction dont la définition est à compléter. [OUT]*
-* data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
-* type1 = type du premier opérande. *
-* type2 = type du second opérande. *
-* ... = éventuelle(s) information(s) complémentaire(s). *
-* *
-* Description : Procède à la lecture de deux opérandes donnés. *
-* *
-* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ va_start(ap, count);
-bool x86_read_two_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, X86OperandType type1, X86OperandType type2, ...)
-{
- va_list ap; /* Liste des compléments */
- AsmOperandSize oprsize; /* Taille des opérandes */
- bool op1_first; /* Position de l'opérande #1 */
- bool op2_first; /* Position de l'opérande #2 */
- off_t op1_pos; /* Position après lecture #1 */
- bin_t base; /* Indice du premier registre */
- GArchOperand *op1; /* Premier opérande décodé */
- off_t op2_pos; /* Position après lecture #2 */
- GArchOperand *op2; /* Second opérande décodé */
+ /* Types à charger */
- va_start(ap, type2);
+ for (i = 0; i < count; i++)
+ types[i] = va_arg(ap, AsmOperandSize);
- oprsize = AOS_UNDEFINED;
+ /* Initialisations */
- if (type1 & X86_OTP_RM_TYPE)
+ if (types[0] & X86_OTP_RM_TYPE)
{
op1_first = true;
op2_first = false;
}
- else if (type2 & X86_OTP_RM_TYPE)
+ else if (types[1] & X86_OTP_RM_TYPE)
{
op1_first = false;
op2_first = true;
@@ -1147,154 +1051,115 @@ bool x86_read_two_operands(GArchInstruction *instr, const bin_t *data, off_t *po
op2_first = false;
}
- /* Lecture du premier opérande */
-
- op1_pos = *pos;
-
- switch (type1)
- {
- case X86_OTP_IMM8:
- op1 = g_imm_operand_new_from_data(MDS_8_BITS, data, &op1_pos, len, SRE_LITTLE);
- break;
-
- case X86_OTP_IMM1632:
- if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
- op1 = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op1_pos, len, SRE_LITTLE);
- break;
-
- case X86_OTP_MOFFS8:
- op1 = g_x86_moffs_operand_new(data, &op1_pos, len, AOS_8_BITS);
- break;
-
- case X86_OTP_MOFFS1632:
- oprsize = va_arg(ap, AsmOperandSize);
- op1 = g_x86_moffs_operand_new(data, &op1_pos, len, oprsize);
- break;
-
- case X86_OTP_R8:
- op1 = g_x86_register_operand_new_from_mod_rm(data, &op1_pos, len, AOS_8_BITS, op1_first);
- break;
-
- case X86_OTP_R1632:
- oprsize = va_arg(ap, AsmOperandSize);
- op1 = g_x86_register_operand_new_from_mod_rm(data, &op1_pos, len, oprsize, op1_first);
- break;
-
- case X86_OTP_OP_R8:
- base = (bin_t)va_arg(ap, int);
- op1 = g_x86_register_operand_new_from_opcode(data, &op1_pos, len, AOS_8_BITS, base);
- break;
-
- case X86_OTP_OP_R1632:
- oprsize = va_arg(ap, AsmOperandSize);
- base = (bin_t)va_arg(ap, int);
- op1 = g_x86_register_operand_new_from_opcode(data, &op1_pos, len, oprsize, base);
- break;
-
- case X86_OTP_RM8:
- op1 = g_x86_mod_rm_operand_new(data, &op1_pos, len, AOS_8_BITS);
- break;
-
- case X86_OTP_RM1632:
- oprsize = va_arg(ap, AsmOperandSize);
- op1 = g_x86_mod_rm_operand_new(data, &op1_pos, len, oprsize);
- break;
-
- case X86_OTP_CL:
- op1 = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS);
- break;
-
- case X86_OTP_AL:
- op1 = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS);
- break;
-
- case X86_OTP_E_AX:
- oprsize = va_arg(ap, AsmOperandSize);
- op1 = g_x86_register_operand_new_from_index(0x00, oprsize);
- break;
-
- }
-
- if (op1 == NULL)
- {
- va_end(ap);
- return false;
- }
-
- /* Lecture du second opérande */
+ oprsize = AOS_UNDEFINED;
- if ((type1 & X86_OTP_REG_TYPE || type1 & X86_OTP_RM_TYPE) && (type2 & X86_OTP_IMM_TYPE))
- op2_pos = op1_pos;
- else op2_pos = *pos;
+ /* Lecture des opérandes */
- switch (type2)
+ for (i = 0; i < count && result; i++)
{
- case X86_OTP_IMM8:
- op2 = g_imm_operand_new_from_data(MDS_8_BITS, data, &op2_pos, len, SRE_LITTLE);
- break;
-
- case X86_OTP_IMM1632:
- if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
- op2 = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op2_pos, len, SRE_LITTLE);
- break;
-
- case X86_OTP_MOFFS8:
- op2 = g_x86_moffs_operand_new(data, &op2_pos, len, AOS_8_BITS);
- break;
-
- case X86_OTP_MOFFS1632:
- if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
- op2 = g_x86_moffs_operand_new(data, &op2_pos, len, oprsize);
- break;
-
- case X86_OTP_R8:
- op2 = g_x86_register_operand_new_from_mod_rm(data, &op2_pos, len, AOS_8_BITS, op2_first);
- break;
-
- case X86_OTP_R1632:
- if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
- op2 = g_x86_register_operand_new_from_mod_rm(data, &op2_pos, len, oprsize, op2_first);
- break;
+ /* Tête de lecture */
+ switch (i)
+ {
+ case 0:
+ op_pos[0] = *pos;
+ break;
- case X86_OTP_RM8:
- op2 = g_x86_mod_rm_operand_new(data, &op2_pos, len, AOS_8_BITS);
- break;
+ case 1:
+ if ((types[0] & X86_OTP_REG_TYPE || types[0] & X86_OTP_RM_TYPE) && (types[1] & X86_OTP_IMM_TYPE))
+ op_pos[1] = op_pos[0];
+ else op_pos[1] = *pos;
+ *pos = op_pos[0];
+ break;
- case X86_OTP_RM1632:
- if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
- op2 = g_x86_mod_rm_operand_new(data, &op2_pos, len, oprsize);
- break;
+ case 2 ... MAX_OPERANDS:
+ *pos = MAX(*pos, op_pos[i - 1]);
+ op_pos[i] = *pos;
- case X86_OTP_CL:
- op2 = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS);
- break;
+ }
- case X86_OTP_AL:
- op2 = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS);
- break;
+ /* Lecture */
+ switch (types[i])
+ {
+ case X86_OTP_IMM8:
+ op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+ break;
+
+ case X86_OTP_IMM1632:
+ if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
+ op = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */);
+ break;
+
+ case X86_OTP_MOFFS8:
+ op = g_x86_moffs_operand_new(data, &op_pos[i], len, AOS_8_BITS);
+ break;
+
+ case X86_OTP_MOFFS1632:
+ if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
+ op = g_x86_moffs_operand_new(data, &op_pos[i], len, oprsize);
+ break;
+
+ case X86_OTP_REL8:
+ offset = va_arg(ap, vmpa_t);
+ op = g_x86_relative_operand_new(data, &op_pos[i], len, AOS_8_BITS, offset + 1);
+ break;
+
+ case X86_OTP_REL1632:
+ if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
+ offset = va_arg(ap, vmpa_t);
+ op = g_x86_relative_operand_new(data, &op_pos[i], len, oprsize, offset + 1);
+ break;
+
+ case X86_OTP_R8:
+ op = g_x86_register_operand_new_from_mod_rm(data, &op_pos[i], len, AOS_8_BITS, i == 0 ? op1_first : op2_first);
+ break;
+
+ case X86_OTP_R1632:
+ if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
+ op = g_x86_register_operand_new_from_mod_rm(data, &op_pos[i], len, oprsize, i == 0 ? op1_first : op2_first);
+ break;
+
+ case X86_OTP_OP_R8:
+ base = (bin_t)va_arg(ap, int);
+ op = g_x86_register_operand_new_from_opcode(data, &op_pos[i], len, AOS_8_BITS, base);
+ break;
+
+ case X86_OTP_OP_R1632:
+ if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
+ base = (bin_t)va_arg(ap, int);
+ op = g_x86_register_operand_new_from_opcode(data, &op_pos[i], len, oprsize, base);
+ break;
+
+ case X86_OTP_RM8:
+ op = g_x86_mod_rm_operand_new(data, &op_pos[i], len, AOS_8_BITS);
+ break;
+
+ case X86_OTP_RM1632:
+ if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
+ op = g_x86_mod_rm_operand_new(data, &op_pos[i], len, oprsize);
+ break;
+
+ case X86_OTP_CL:
+ op = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS);
+ break;
+
+ case X86_OTP_AL:
+ op = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS);
+ break;
+
+ case X86_OTP_E_AX:
+ if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
+ op = g_x86_register_operand_new_from_index(0x00, oprsize);
+ break;
- case X86_OTP_E_AX:
- if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize);
- op2 = g_x86_register_operand_new_from_index(0x00, oprsize);
- break;
+ }
- }
+ if (op == NULL) result = false;
+ else g_arch_instruction_attach_extra_operand(instr, op);
- if (op2 == NULL)
- {
- free(op1);
- va_end(ap);
- return false;
}
- va_end(ap);
-
- /* Assemblage final */
-
- *pos = MAX(op1_pos, op2_pos);
-
- g_arch_instruction_attach_two_operands(instr, op1, op2);
+ *pos = MAX(*pos, op_pos[i - 1]);
- return true;
+ return result;
}
diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h
index cb04ca8..fc40b38 100644
--- a/src/arch/x86/operand.h
+++ b/src/arch/x86/operand.h
@@ -207,11 +207,16 @@ typedef enum _X86OperandType
} X86OperandType;
-/* Procède à la lecture d'un opérande donné. */
-bool x86_read_one_operand(GArchInstruction *, const bin_t *data, off_t *pos, off_t, X86OperandType, ...);
+/* Nombre maximal d'opérande */
+#define MAX_OPERANDS 3
-/* Procède à la lecture de deux opérandes donnés. */
-bool x86_read_two_operands(GArchInstruction *, const bin_t *data, off_t *pos, off_t, X86OperandType, X86OperandType, ...);
+
+#define x86_read_one_operand(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 1, __VA_ARGS__)
+#define x86_read_two_operands(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 2, __VA_ARGS__)
+#define x86_read_three_operands(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 3, __VA_ARGS__)
+
+/* Procède à la lecture de n opérandes donnés. */
+bool _x86_read_operands(GArchInstruction *, const bin_t *, off_t *, off_t, unsigned int, ...);
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 15179e2..3dc5fc2 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -225,6 +225,19 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
result = x86_read_instr_or_rm1632_r1632(data, pos, len, addr, prefix, proc);
break;
+
+
+ case XOP_AND_AL_IMM8:
+ result = x86_read_instr_and_al_imm8(data, pos, len, addr, prefix, proc);
+ break;
+
+ case XOP_AND_E_AX_IMM1632:
+ result = x86_read_instr_and_e_ax_imm1632(data, pos, len, addr, prefix, proc);
+ break;
+
+
+
+
case XOP_OR_R8_RM8:
result = x86_read_instr_or_r8_rm8(data, pos, len, addr, prefix, proc);
break;
@@ -246,6 +259,9 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
result = x86_read_instr_jne_rel1632(data, pos, len, addr, prefix, proc);
break;
+ case XOP_JBE_REL1632:
+ result = x86_read_instr_jbe_rel1632(data, pos, len, addr, prefix, proc);
+ break;
case XOP_JA_REL1632:
result = x86_read_instr_ja_rel1632(data, pos, len, addr, prefix, proc);
@@ -270,6 +286,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
result = x86_read_instr_jle_rel1632(data, pos, len, addr, prefix, proc);
break;
+ case XOP_JG_REL1632:
+ result = x86_read_instr_jg_rel1632(data, pos, len, addr, prefix, proc);
+ break;
+
case XOP_MOVZX_R1632_RM8:
result = x86_read_instr_movzx_r1632_rm8(data, pos, len, addr, prefix, proc);
@@ -291,6 +311,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
result = x86_read_instr_and_rm8_r8(data, pos, len, addr, prefix, proc);
break;
+ case XOP_AND_RM1632_R1632:
+ result = x86_read_instr_and_rm1632_r1632(data, pos, len, addr, prefix, proc);
+ break;
+
case XOP_SUB_RM1632_R1632:
result = x86_read_instr_sub_rm1632_r1632(data, pos, len, addr, prefix, proc);
@@ -342,6 +366,13 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
result = x86_read_instr_cmp_rm1632_r1632(data, pos, len, addr, prefix, proc);
break;
+
+ case XOP_CMP_R1632_RM1632:
+ result = x86_read_instr_cmp_r1632_rm1632(data, pos, len, addr, prefix, proc);
+ break;
+
+
+
case XOP_INC_E_AX:
case XOP_INC_E_CX:
case XOP_INC_E_DX:
@@ -391,6 +422,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
result = x86_read_instr_push_imm1632(data, pos, len, addr, prefix, proc);
break;
+ case XOP_IMUL_R1632_RM1632_IMM1632:
+ result = x86_read_instr_imul_r1632_rm1632_imm1632(data, pos, len, addr, prefix, proc);
+ break;
+
case XOP_IMUL_RM1632_IMM8:
result = x86_read_instr_imul_rm1632_imm8(data, pos, len, addr, prefix, proc);