Beginning to get the Mod R/M byte right (not considering the SIB at all)
This commit is contained in:
parent
0ff490e2a0
commit
e853ba8c28
@ -67,11 +67,10 @@ typedef enum _ArchOperandType
|
||||
# define AOM_VALUE 0x000000ff
|
||||
|
||||
/* flags */
|
||||
# define AOF_FILTER 0x1
|
||||
/* for immediate */
|
||||
# define AOF_SIGNED 0x2
|
||||
# define AOF_SIGNED 0x1
|
||||
/* for registers */
|
||||
# define AOF_IMPLICIT 0x2
|
||||
# define AOF_IMPLICIT 0x1
|
||||
|
||||
/* macros */
|
||||
# define AO_GET_FLAGS(operand) ((operand & AOM_FLAGS) >> AOD_FLAGS)
|
||||
|
@ -118,17 +118,51 @@ static int _i386_write(ArchPlugin * plugin, ArchInstruction * instruction,
|
||||
static int _write_dregister(ArchPlugin * plugin,
|
||||
ArchOperandDefinition definition, ArchOperand * operand)
|
||||
{
|
||||
/* FIXME really implement */
|
||||
return _write_register(plugin, definition, operand);
|
||||
ArchPluginHelper * helper = plugin->helper;
|
||||
char const * name = operand->value._register.name;
|
||||
size_t size = AO_GET_SIZE(definition);
|
||||
ArchRegister * ar;
|
||||
ArchOperandDefinition idefinition;
|
||||
ArchOperand ioperand;
|
||||
|
||||
if((ar = helper->get_register_by_name_size(helper->arch, name, size))
|
||||
== NULL)
|
||||
return -1;
|
||||
/* write register */
|
||||
idefinition = AO_IMMEDIATE(0, 0, 8);
|
||||
memset(&ioperand, 0, sizeof(ioperand));
|
||||
ioperand.type = AOT_IMMEDIATE;
|
||||
ioperand.value.immediate.value = ar->id;
|
||||
if(AO_GET_FLAGS(definition) & AOF_I386_MODRM)
|
||||
ioperand.value.immediate.value |= (AO_GET_VALUE(definition)
|
||||
<< 3);
|
||||
if(operand->value.dregister.offset == 0)
|
||||
/* there is no offset */
|
||||
return _write_immediate(plugin, idefinition, &ioperand);
|
||||
/* declare offset */
|
||||
switch(AO_GET_OFFSET(definition) >> 3)
|
||||
{
|
||||
case sizeof(uint8_t):
|
||||
ioperand.value.immediate.value |= 0x40;
|
||||
break;
|
||||
case W >> 3:
|
||||
ioperand.value.immediate.value |= 0x80;
|
||||
break;
|
||||
default:
|
||||
return -1; /* FIXME report error */
|
||||
}
|
||||
if(_write_immediate(plugin, idefinition, &ioperand) != 0)
|
||||
return -1;
|
||||
/* write offset */
|
||||
idefinition = AO_IMMEDIATE(0, 0, AO_GET_OFFSET(definition));
|
||||
ioperand.value.immediate.value = operand->value.dregister.offset;
|
||||
return _write_immediate(plugin, idefinition, &ioperand);
|
||||
}
|
||||
|
||||
static int _write_immediate(ArchPlugin * plugin,
|
||||
ArchOperandDefinition definition, ArchOperand * operand)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
size = AO_GET_SIZE(definition) >> 3;
|
||||
switch(size)
|
||||
switch(AO_GET_SIZE(definition) >> 3)
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
@ -231,6 +265,10 @@ static int _write_register(ArchPlugin * plugin,
|
||||
idefinition = AO_IMMEDIATE(0, 0, 8);
|
||||
memset(&ioperand, 0, sizeof(ioperand));
|
||||
ioperand.type = AOT_IMMEDIATE;
|
||||
ioperand.value.immediate.value = ar->id;
|
||||
if(AO_GET_FLAGS(definition) & AOF_I386_MODRM)
|
||||
ioperand.value.immediate.value = 0xc0 | ar->id
|
||||
| (AO_GET_VALUE(definition) << 3);
|
||||
else
|
||||
ioperand.value.immediate.value = ar->id;
|
||||
return _write_immediate(plugin, idefinition, &ioperand);
|
||||
}
|
||||
|
@ -7,40 +7,55 @@
|
||||
# define REG_AX_id REG_eax_id
|
||||
#endif
|
||||
|
||||
|
||||
/* helpers */
|
||||
/* opcodes */
|
||||
#define OP1F (8 << AOD_SIZE)
|
||||
#define OP2F (16 << AOD_SIZE)
|
||||
|
||||
/* operands */
|
||||
/* registers */
|
||||
#define OP_R8 AO_REGISTER(0, 8, 0)
|
||||
#define OP_RW AO_REGISTER(0, W, 0)
|
||||
#define OP_al AO_REGISTER(AOF_IMPLICIT, REG_al_size, REG_al_id)
|
||||
#define OP_AX AO_REGISTER(AOF_IMPLICIT, W, REG_AX_id)
|
||||
|
||||
/* helpers */
|
||||
#define OP1F (8 << AOD_SIZE)
|
||||
#define OP2F (16 << AOD_SIZE)
|
||||
/* mod r/m byte */
|
||||
#define OP_RM8_D0 AO_DREGISTER(0, 0, 8, 0)
|
||||
#define OP_RM8_D8 AO_DREGISTER(0, 8, 8, 0)
|
||||
#define OP_RM8_DW AO_DREGISTER(0, W, 8, 0)
|
||||
#define OP_RM8_RW AO_REGISTER(0, 8, 0)
|
||||
#define OP_RMW_D0 AO_DREGISTER(0, 0, W, 0)
|
||||
#define OP_RMW_D8 AO_DREGISTER(0, 8, W, 0)
|
||||
#define OP_RMW_DW AO_DREGISTER(0, W, W, 0)
|
||||
#define OP_RMW_RW AO_REGISTER(0, W, 0)
|
||||
#define AOF_I386_MODRM 0x2
|
||||
#define OP_RM8_D0 AO_DREGISTER(AOF_I386_MODRM, 0, W, 0) /* 0x00 */
|
||||
#define OP_RM8_D8 AO_DREGISTER(AOF_I386_MODRM, 8, W, 0) /* 0x40 */
|
||||
#define OP_RM8_DW AO_DREGISTER(AOF_I386_MODRM, W, W, 0) /* 0x80 */
|
||||
#define OP_RM8_R8 AO_REGISTER(AOF_I386_MODRM, 8, 0) /* 0xc0 */
|
||||
#define OP_RMW_D0 AO_DREGISTER(AOF_I386_MODRM, 0, W, 0) /* 0x00 */
|
||||
#define OP_RMW_D8 AO_DREGISTER(AOF_I386_MODRM, 8, W, 0) /* 0x40 */
|
||||
#define OP_RMW_DW AO_DREGISTER(AOF_I386_MODRM, W, W, 0) /* 0x80 */
|
||||
#define OP_RMW_RW AO_REGISTER(AOF_I386_MODRM, W, 0) /* 0xc0 */
|
||||
|
||||
/* immediate values */
|
||||
#define OP_U8 AO_IMMEDIATE(0, 0, 8)
|
||||
#define OP_UW AO_IMMEDIATE(0, 0, W)
|
||||
|
||||
|
||||
/* instructions */
|
||||
{ "aaa", 0x37, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },
|
||||
{ "aad", 0xd50a, OP2F, AOT_NONE, AOT_NONE, AOT_NONE },
|
||||
{ "aad", 0xd5, OP1F, OP_U8, AOT_NONE, AOT_NONE },
|
||||
{ "aam", 0xd40a, OP2F, AOT_NONE, AOT_NONE, AOT_NONE },
|
||||
{ "aam", 0xd4, OP1F, OP_U8, AOT_NONE, AOT_NONE },
|
||||
{ "aas", 0x3f, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },
|
||||
{ "adc", 0x14, OP1F, OP_al, OP_U8, AOT_NONE },
|
||||
{ "adc", 0x15, OP1F, OP_AX, OP_UW, AOT_NONE },
|
||||
{ "adc", 0x80, OP1F, OP_RM8_D0,OP_U8, AOT_NONE },
|
||||
{ "adc", 0x80, OP1F, OP_RM8_D8,OP_U8, AOT_NONE },
|
||||
{ "adc", 0x80, OP1F, OP_RM8_DW,OP_U8, AOT_NONE },
|
||||
{ "adc", 0x80, OP1F, OP_RM8_RW,OP_U8, AOT_NONE },
|
||||
{ "adc", 0x81, OP1F, OP_RMW_D0,OP_UW, AOT_NONE },
|
||||
{ "adc", 0x81, OP1F, OP_RMW_D8,OP_UW, AOT_NONE },
|
||||
{ "adc", 0x81, OP1F, OP_RMW_DW,OP_UW, AOT_NONE },
|
||||
{ "adc", 0x81, OP1F, OP_RMW_RW,OP_UW, AOT_NONE },
|
||||
{ "nop", 0x90, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },
|
||||
/* ADC 0x14 ib 1 al imm8 */
|
||||
{ "adc", 0x14, OP1F, OP_al, OP_U8, AOT_NONE },
|
||||
/* ADC 0x15 iW 1 AX immW */
|
||||
{ "adc", 0x15, OP1F, OP_AX, OP_UW, AOT_NONE },
|
||||
/* ADC 0x80 /2 ib 1 r/m8 imm8 */
|
||||
{ "adc", 0x80, OP1F, OP_RM8_D0+2,OP_U8, AOT_NONE },
|
||||
{ "adc", 0x80, OP1F, OP_RM8_D8+2,OP_U8, AOT_NONE },
|
||||
{ "adc", 0x80, OP1F, OP_RM8_DW+2,OP_U8, AOT_NONE },
|
||||
{ "adc", 0x80, OP1F, OP_RM8_R8+2,OP_U8, AOT_NONE },
|
||||
/* ADC 0x81 /2 iW 1 r/m8 imm8 */
|
||||
{ "adc", 0x81, OP1F, OP_RMW_D0+2,OP_UW, AOT_NONE },
|
||||
{ "adc", 0x81, OP1F, OP_RMW_D8+2,OP_UW, AOT_NONE },
|
||||
{ "adc", 0x81, OP1F, OP_RMW_DW+2,OP_UW, AOT_NONE },
|
||||
{ "adc", 0x81, OP1F, OP_RMW_RW+2,OP_UW, AOT_NONE },
|
||||
/* NOP */
|
||||
{ "nop", 0x90, OP1F, AOT_NONE, AOT_NONE, AOT_NONE },
|
||||
|
21
test/i386.S
21
test/i386.S
@ -1,3 +1,4 @@
|
||||
/* $Id$ */
|
||||
.text
|
||||
aaa
|
||||
aad
|
||||
@ -5,11 +6,17 @@
|
||||
aam
|
||||
aam $0x42
|
||||
aas
|
||||
adc %al, $0x42
|
||||
adc %eax, $0x42
|
||||
adc [%edx], $0x42
|
||||
adc [%ebx + $0x5], $0x42
|
||||
adc %ecx, $0x42
|
||||
adc [%edx], $0x42434445
|
||||
adc %ebx, $0x42434445
|
||||
/* ADC */
|
||||
adc %al, $0x40 /* 14 40 */
|
||||
adc %eax, $0x41424344 /* 15 41 42 43 44 */
|
||||
adc [%edx], $0x46 /* 80 12 46 */
|
||||
adc [%ebx + $0x15], $0x47 /* 80 53 15 47 */
|
||||
adc [%ebx + $0x16171819], $0x48 /* 80 93 19 18 17 16 48 */
|
||||
adc %cl, $0x45 /* 80 d1 45 */
|
||||
adc [%edx], $0x46474849 /* 81 12 46 47 48 49 */
|
||||
adc [%ebx + $0x14], $0x4748494a /* 81 53 14 47 48 49 4a */
|
||||
adc [%ebx + $0x16171819], $0x48494a4b
|
||||
/* 81 93 19 18 17 16 4b */
|
||||
/* 4a 49 48 */
|
||||
adc %ecx, $0x45464748 /* 81 d1 45 46 47 48 */
|
||||
nop
|
||||
|
Loading…
Reference in New Issue
Block a user