Fixed several disassembler bugs
Prepared for AT&T style support in Bochs disassembler - it already supports all AT&T style except opcode name suffixes - AT&T support in future will be possible to enable from bx_debugger
This commit is contained in:
parent
5a36efedfa
commit
9d1b401512
@ -58,6 +58,9 @@ Changes to next release:
|
||||
- fixed INS opcode 0x6D, had wrong operand size (Stanislav)
|
||||
- fixed disassembly for repeatable instructions (Stanislav)
|
||||
- fixed sign-extended immediate opcodes (Stanislav)
|
||||
- fixed MOVSS/MOVSD instructions opcode names (Stanislav)
|
||||
- fixed NEG instruction opcode name (Stanislav)
|
||||
- fixed floating point instructions arguments (Stanislav)
|
||||
|
||||
- I/O devices
|
||||
- general
|
||||
@ -171,6 +174,9 @@ Changes to next release:
|
||||
- patch.apic-zwane (APIC fixes) (Zwane Mwaikambo)
|
||||
|
||||
- these S.F. bugs were closed
|
||||
#1071199 dBaseII cause prefetch: RIP > CS limit
|
||||
#1070812 typecast error while compiling wx.cc
|
||||
#1068786 FSINCOS Cos value wrong at 90 degrees
|
||||
#675248 Panic: EIP > limit on win98 install
|
||||
#829793 [CPU ] prefetch: RIP > CS.limit
|
||||
#1034059 >>PANIC<< prefetch: running in bogus memory
|
||||
|
@ -48,7 +48,8 @@ RANLIB = @RANLIB@
|
||||
BX_OBJS = \
|
||||
dis_decode.o \
|
||||
dis_groups.o \
|
||||
resolve.o
|
||||
resolve.o \
|
||||
syntax.o
|
||||
|
||||
BX_INCLUDES = disasm.h
|
||||
|
||||
@ -83,3 +84,4 @@ dist-clean: clean
|
||||
dis_decode.o: dis_decode.@CPP_SUFFIX@ disasm.h ../config.h dis_tables.h
|
||||
dis_groups.o: dis_groups.@CPP_SUFFIX@ disasm.h ../config.h
|
||||
resolve.o: resolve.@CPP_SUFFIX@ disasm.h ../config.h
|
||||
syntax.o: syntax.@CPP_SUFFIX@ disasm.h ../config.h
|
||||
|
@ -75,10 +75,6 @@ static const unsigned char instruction_has_modrm[512] = {
|
||||
*
|
||||
* 66h - operand size override prefix
|
||||
* 67h - address size override prefix
|
||||
*
|
||||
* For each instruction, one prefix may be used from each of these groups
|
||||
* and be placed in any order. Using redundant prefixes (more than one
|
||||
* prefix from a group) is reserved and will cause undefined behaviour.
|
||||
*/
|
||||
|
||||
unsigned disassembler::disasm(bx_bool is_32,
|
||||
@ -216,14 +212,31 @@ unsigned disassembler::disasm(bx_bool is_32,
|
||||
// print opcode
|
||||
dis_sprintf("%s ", entry->Opcode);
|
||||
|
||||
(this->*entry->Operand1)(entry->Op1Attr);
|
||||
if (entry->Operand2 != &disassembler::XX)
|
||||
if (intel_mode)
|
||||
{
|
||||
(this->*entry->Operand1)(entry->Op1Attr);
|
||||
if (entry->Operand2 != &disassembler::XX) {
|
||||
dis_sprintf(", ");
|
||||
(this->*entry->Operand2)(entry->Op2Attr);
|
||||
if (entry->Operand3 != &disassembler::XX)
|
||||
(this->*entry->Operand2)(entry->Op2Attr);
|
||||
}
|
||||
if (entry->Operand3 != &disassembler::XX) {
|
||||
dis_sprintf(", ");
|
||||
(this->*entry->Operand3)(entry->Op3Attr);
|
||||
|
||||
(this->*entry->Operand3)(entry->Op3Attr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entry->Operand3 != &disassembler::XX) {
|
||||
(this->*entry->Operand3)(entry->Op3Attr);
|
||||
dis_sprintf(", ");
|
||||
}
|
||||
if (entry->Operand2 != &disassembler::XX) {
|
||||
(this->*entry->Operand2)(entry->Op2Attr);
|
||||
dis_sprintf(", ");
|
||||
}
|
||||
(this->*entry->Operand1)(entry->Op1Attr);
|
||||
}
|
||||
|
||||
return(instruction - instruction_begin);
|
||||
}
|
||||
|
||||
|
@ -1,51 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "disasm.h"
|
||||
|
||||
#if BX_DEBUGGER
|
||||
#include "../bx_debug/debug.h"
|
||||
#endif
|
||||
|
||||
//////////////////
|
||||
// Intel STYLE
|
||||
//////////////////
|
||||
|
||||
static const char *general_8bit_reg_name[8] = {
|
||||
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
|
||||
};
|
||||
|
||||
const char *general_16bit_reg_name[8] = {
|
||||
"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
|
||||
};
|
||||
|
||||
const char *general_32bit_reg_name[8] = {
|
||||
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
|
||||
};
|
||||
|
||||
static const char *segment_name[8] = {
|
||||
"es", "cs", "ss", "ds", "fs", "gs", "??", "??"
|
||||
};
|
||||
|
||||
static const char *mmx_reg_name[8] = {
|
||||
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"
|
||||
};
|
||||
|
||||
static const char *xmm_reg_name[8] =
|
||||
{
|
||||
"xmm0",
|
||||
"xmm1",
|
||||
"xmm2",
|
||||
"xmm3",
|
||||
"xmm4",
|
||||
"xmm5",
|
||||
"xmm6",
|
||||
"xmm7"
|
||||
};
|
||||
|
||||
void disassembler::reg32 (unsigned attr)
|
||||
{
|
||||
assert(attr < 8);
|
||||
|
||||
if (i32bit_opsize)
|
||||
dis_sprintf("%s", general_32bit_reg_name[attr]);
|
||||
else
|
||||
@ -54,34 +15,36 @@ void disassembler::reg32 (unsigned attr)
|
||||
|
||||
void disassembler::reg16 (unsigned attr)
|
||||
{
|
||||
assert(attr < 8);
|
||||
dis_sprintf("%s", general_16bit_reg_name[attr]);
|
||||
}
|
||||
|
||||
void disassembler::reg8 (unsigned attr)
|
||||
{
|
||||
assert(attr < 8);
|
||||
dis_sprintf("%s", general_8bit_reg_name[attr]);
|
||||
}
|
||||
|
||||
void disassembler::OP_SEG (unsigned attr)
|
||||
{
|
||||
assert(attr < 8);
|
||||
dis_sprintf("%s", segment_name[attr]);
|
||||
}
|
||||
|
||||
void disassembler::OP_MEM (unsigned attr)
|
||||
{
|
||||
if(mod == 3)
|
||||
if(mod == 3)
|
||||
dis_sprintf("(bad)");
|
||||
else
|
||||
else
|
||||
(this->*resolve_modrm)(attr);
|
||||
}
|
||||
|
||||
void disassembler::OP_Q (unsigned attr)
|
||||
{
|
||||
if (mod == 3)
|
||||
dis_sprintf("%s", mmx_reg_name[rm]);
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("mm%d", rm);
|
||||
else
|
||||
dis_sprintf("%%mm%d", rm);
|
||||
}
|
||||
else
|
||||
(this->*resolve_modrm)(attr);
|
||||
}
|
||||
@ -89,19 +52,30 @@ void disassembler::OP_Q (unsigned attr)
|
||||
void disassembler::OP_W (unsigned attr)
|
||||
{
|
||||
if (mod == 3)
|
||||
dis_sprintf("%s", xmm_reg_name[rm]);
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("xmm%d", rm);
|
||||
else
|
||||
dis_sprintf("%%xmm%d", rm);
|
||||
}
|
||||
else
|
||||
(this->*resolve_modrm)(attr);
|
||||
}
|
||||
|
||||
void disassembler::OP_V (unsigned attr)
|
||||
{
|
||||
dis_sprintf("%s", xmm_reg_name[nnn]);
|
||||
if (intel_mode)
|
||||
dis_sprintf ("xmm%d", nnn);
|
||||
else
|
||||
dis_sprintf("%%xmm%d", nnn);
|
||||
}
|
||||
|
||||
void disassembler::OP_P (unsigned attr)
|
||||
{
|
||||
dis_sprintf("%s", mmx_reg_name[nnn]);
|
||||
if (intel_mode)
|
||||
dis_sprintf ("mm%d", nnn);
|
||||
else
|
||||
dis_sprintf("%%mm%d", nnn);
|
||||
}
|
||||
|
||||
void disassembler::OP_X (unsigned attr)
|
||||
@ -109,25 +83,38 @@ void disassembler::OP_X (unsigned attr)
|
||||
const char *esi, *seg;
|
||||
|
||||
if (i32bit_addrsize)
|
||||
esi = "esi";
|
||||
esi = general_32bit_reg_name[eSI_REG];
|
||||
else
|
||||
esi = "si";
|
||||
esi = general_16bit_reg_name[eSI_REG];
|
||||
|
||||
if (attr & ES_SEG)
|
||||
{
|
||||
seg = "es";
|
||||
}
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
{
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = "ds";
|
||||
}
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
print_datasize(attr & 0x7F);
|
||||
print_datasize(attr);
|
||||
|
||||
dis_sprintf("%s:[%s]", seg, esi);
|
||||
if (intel_mode)
|
||||
dis_sprintf("%s:[%s]", seg, esi);
|
||||
else
|
||||
dis_sprintf("%s:(%s)", seg, esi);
|
||||
}
|
||||
|
||||
void disassembler::OP_Xe (unsigned attr)
|
||||
{
|
||||
const char *esi;
|
||||
|
||||
if (i32bit_addrsize)
|
||||
esi = general_32bit_reg_name[eSI_REG];
|
||||
else
|
||||
esi = general_16bit_reg_name[eSI_REG];
|
||||
|
||||
print_datasize(attr);
|
||||
|
||||
if (intel_mode)
|
||||
dis_sprintf("%s:[%s]", segment_name[ES_REG], esi);
|
||||
else
|
||||
dis_sprintf("%s:(%s)", segment_name[ES_REG], esi);
|
||||
}
|
||||
|
||||
void disassembler::OP_Y (unsigned attr)
|
||||
@ -135,25 +122,38 @@ void disassembler::OP_Y (unsigned attr)
|
||||
const char *edi, *seg;
|
||||
|
||||
if (i32bit_addrsize)
|
||||
edi = "edi";
|
||||
edi = general_32bit_reg_name[eDI_REG];
|
||||
else
|
||||
edi = "di";
|
||||
edi = general_16bit_reg_name[eDI_REG];
|
||||
|
||||
if (attr & ES_SEG)
|
||||
{
|
||||
seg = "es";
|
||||
}
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
{
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = "ds";
|
||||
}
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
print_datasize(attr & 0x7F);
|
||||
print_datasize(attr);
|
||||
|
||||
dis_sprintf("%s:[%s]", seg, edi);
|
||||
if (intel_mode)
|
||||
dis_sprintf("%s:[%s]", seg, edi);
|
||||
else
|
||||
dis_sprintf("%s:(%s)", seg, edi);
|
||||
}
|
||||
|
||||
void disassembler::OP_Ye (unsigned attr)
|
||||
{
|
||||
const char *edi;
|
||||
|
||||
if (i32bit_addrsize)
|
||||
edi = general_32bit_reg_name[eDI_REG];
|
||||
else
|
||||
edi = general_16bit_reg_name[eDI_REG];
|
||||
|
||||
print_datasize(attr);
|
||||
|
||||
if (intel_mode)
|
||||
dis_sprintf("%s:[%s]", segment_name[ES_REG], edi);
|
||||
else
|
||||
dis_sprintf("%s:(%s)", segment_name[ES_REG], edi);
|
||||
}
|
||||
|
||||
void disassembler::Ob (unsigned attr)
|
||||
@ -163,7 +163,7 @@ void disassembler::Ob (unsigned attr)
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = "ds";
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
if (i32bit_addrsize) {
|
||||
Bit32u imm32 = fetch_dword();
|
||||
@ -182,7 +182,7 @@ void disassembler::Ov (unsigned attr)
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = "ds";
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
if (i32bit_addrsize) {
|
||||
Bit32u imm32 = fetch_dword();
|
||||
@ -206,7 +206,7 @@ void disassembler::Jb (unsigned attr)
|
||||
}
|
||||
else // Symbol not found
|
||||
#endif
|
||||
dis_sprintf("0x%x", (unsigned) (imm8+db_eip));
|
||||
dis_sprintf(".+0x%x", (unsigned) (imm8+db_eip));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -217,7 +217,7 @@ void disassembler::Jb (unsigned attr)
|
||||
}
|
||||
else // Symbol not found
|
||||
#endif
|
||||
dis_sprintf("0x%x", (unsigned) ((imm8+db_eip) & 0xFFFF));
|
||||
dis_sprintf(".+0x%x", (unsigned) ((imm8+db_eip) & 0xFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ void disassembler::Jv (unsigned attr)
|
||||
}
|
||||
else // Symbol not found
|
||||
#endif
|
||||
dis_sprintf("0x%x", (unsigned) (imm32+db_eip));
|
||||
dis_sprintf(".+0x%x", (unsigned) (imm32+db_eip));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -246,7 +246,7 @@ void disassembler::Jv (unsigned attr)
|
||||
}
|
||||
else // Symbol not found
|
||||
#endif
|
||||
dis_sprintf("0x%x", (unsigned) ((imm16+db_eip) & 0xFFFF));
|
||||
dis_sprintf(".+0x%x", (unsigned) ((imm16+db_eip) & 0xFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,12 +323,12 @@ void disassembler::Gd (unsigned attr)
|
||||
|
||||
void disassembler::Rd (unsigned attr)
|
||||
{
|
||||
dis_sprintf("%s", general_32bit_reg_name[rm]);
|
||||
dis_sprintf("%s", general_32bit_reg_name[rm]);
|
||||
}
|
||||
|
||||
void disassembler::Rw (unsigned attr)
|
||||
{
|
||||
dis_sprintf("%s", general_16bit_reg_name[rm]);
|
||||
dis_sprintf("%s", general_16bit_reg_name[rm]);
|
||||
}
|
||||
|
||||
void disassembler::Sw (unsigned attr)
|
||||
@ -336,19 +336,36 @@ void disassembler::Sw (unsigned attr)
|
||||
dis_sprintf("%s", segment_name[nnn]);
|
||||
}
|
||||
|
||||
void disassembler::I1 (unsigned)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("1");
|
||||
else
|
||||
dis_sprintf("$1");
|
||||
}
|
||||
|
||||
void disassembler::Ib (unsigned attr)
|
||||
{
|
||||
dis_sprintf("0x%x", (unsigned) fetch_byte());
|
||||
if (intel_mode)
|
||||
dis_sprintf ("0x%x", (unsigned) fetch_byte());
|
||||
else
|
||||
dis_sprintf("$0x%x", (unsigned) fetch_byte());
|
||||
}
|
||||
|
||||
void disassembler::Iw (unsigned attr)
|
||||
{
|
||||
dis_sprintf("0x%x", (unsigned) fetch_word());
|
||||
if (intel_mode)
|
||||
dis_sprintf ("0x%x", (unsigned) fetch_word());
|
||||
else
|
||||
dis_sprintf("$0x%x", (unsigned) fetch_word());
|
||||
}
|
||||
|
||||
void disassembler::Id (unsigned attr)
|
||||
{
|
||||
dis_sprintf("0x%x", (unsigned) fetch_dword());
|
||||
if (intel_mode)
|
||||
dis_sprintf ("0x%x", (unsigned) fetch_dword());
|
||||
else
|
||||
dis_sprintf("$0x%x", (unsigned) fetch_dword());
|
||||
}
|
||||
|
||||
void disassembler::Iv (unsigned attr)
|
||||
@ -364,14 +381,61 @@ void disassembler::sIb(unsigned attr)
|
||||
if (i32bit_opsize)
|
||||
{
|
||||
Bit32u imm32 = (Bit8s) fetch_byte();
|
||||
dis_sprintf("0x%x", (unsigned) imm32);
|
||||
if (intel_mode)
|
||||
dis_sprintf ("0x%x", (unsigned) imm32);
|
||||
else
|
||||
dis_sprintf("$0x%x", (unsigned) imm32);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bit16u imm16 = (Bit8s) fetch_byte();
|
||||
dis_sprintf("0x%x", (unsigned) imm16);
|
||||
if (intel_mode)
|
||||
dis_sprintf ("0x%x", (unsigned) imm16);
|
||||
else
|
||||
dis_sprintf("$0x%x", (unsigned) imm16);
|
||||
}
|
||||
}
|
||||
|
||||
// floating point
|
||||
void disassembler::STj (unsigned attr) { dis_sprintf("st(%d)", rm); }
|
||||
void disassembler::ST0 (unsigned attr)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("st(0)");
|
||||
else
|
||||
dis_sprintf("%%st(0)");
|
||||
}
|
||||
|
||||
void disassembler::STj (unsigned attr)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("st(%d)", rm);
|
||||
else
|
||||
dis_sprintf("%%st(%d)", rm);
|
||||
}
|
||||
|
||||
// control register
|
||||
void disassembler::Cd (unsigned attr)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("cr%d", nnn);
|
||||
else
|
||||
dis_sprintf("%%cr%d", nnn);
|
||||
}
|
||||
|
||||
// debug register
|
||||
void disassembler::Dd (unsigned attr)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("db%d", nnn);
|
||||
else
|
||||
dis_sprintf("%%db%d", nnn);
|
||||
}
|
||||
|
||||
// test registers
|
||||
void disassembler::Td (unsigned attr)
|
||||
{
|
||||
if (intel_mode)
|
||||
dis_sprintf ("tr%d", nnn);
|
||||
else
|
||||
dis_sprintf("%%tr%d", nnn);
|
||||
}
|
||||
|
@ -15,11 +15,11 @@ struct BxDisasmOpcodeInfo_t
|
||||
const char *Opcode;
|
||||
Bit32u Attr;
|
||||
BxDisasmPtr_t Operand1;
|
||||
unsigned Op1Attr;
|
||||
unsigned Op1Attr;
|
||||
BxDisasmPtr_t Operand2;
|
||||
unsigned Op2Attr;
|
||||
unsigned Op2Attr;
|
||||
BxDisasmPtr_t Operand3;
|
||||
unsigned Op3Attr;
|
||||
unsigned Op3Attr;
|
||||
struct BxDisasmOpcodeInfo_t *AnotherArray;
|
||||
};
|
||||
|
||||
@ -119,13 +119,13 @@ struct BxDisasmOpcodeInfo_t
|
||||
|
||||
// string instructions
|
||||
#define Xb &disassembler::OP_X, B_MODE
|
||||
#define Xbe &disassembler::OP_X, B_MODE|ES_SEG
|
||||
#define Xbe &disassembler::OP_Xe, B_MODE
|
||||
#define Yb &disassembler::OP_Y, B_MODE
|
||||
#define Ybe &disassembler::OP_Y, B_MODE|ES_SEG
|
||||
#define Ybe &disassembler::OP_Ye, B_MODE
|
||||
#define Xv &disassembler::OP_X, V_MODE
|
||||
#define Xve &disassembler::OP_X, V_MODE|ES_SEG
|
||||
#define Xve &disassembler::OP_Xe, V_MODE
|
||||
#define Yv &disassembler::OP_Y, V_MODE
|
||||
#define Yve &disassembler::OP_Y, V_MODE|ES_SEG
|
||||
#define Yve &disassembler::OP_Ye, V_MODE
|
||||
|
||||
// immediate
|
||||
#define I1 &disassembler::I1, 0
|
||||
@ -180,15 +180,15 @@ struct BxDisasmOpcodeInfo_t
|
||||
static BxDisasmOpcodeInfo_t BxDisasmGroupSSE_0f10[4] = {
|
||||
/* -- */ { "movups", 0, Vps, Wps, XX },
|
||||
/* 66 */ { "movupd", 0, Vpd, Wpd, XX },
|
||||
/* F2 */ { "movdq", 0, Vdq, Wdq, XX },
|
||||
/* F3 */ { "movdq", 0, Vdq, Wdq, XX }
|
||||
/* F2 */ { "movsd", 0, Vsd, Wsd, XX },
|
||||
/* F3 */ { "movss", 0, Vss, Wss, XX }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeInfo_t BxDisasmGroupSSE_0f11[4] = {
|
||||
/* -- */ { "movups", 0, Wps, Vps, XX },
|
||||
/* 66 */ { "movupd", 0, Wpd, Vpd, XX },
|
||||
/* F2 */ { "movdq", 0, Wdq, Vdq, XX },
|
||||
/* F3 */ { "movdq", 0, Wdq, Vdq, XX }
|
||||
/* F2 */ { "movsd", 0, Wsd, Vsd, XX },
|
||||
/* F3 */ { "movss", 0, Wss, Vss, XX }
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeInfo_t BxDisasmGroupSSE_0f12[4] = {
|
||||
@ -509,7 +509,7 @@ static BxDisasmOpcodeInfo_t BxDisasmGroupSSE_0f6e[4] = {
|
||||
static BxDisasmOpcodeInfo_t BxDisasmGroupSSE_0f6f[4] = {
|
||||
/* -- */ { "movq", 0, Pq, Qq, XX },
|
||||
/* 66 */ { "movdqa", 0, Vdq, Wdq, XX },
|
||||
/* F2 */ { "movdqa", 0, XX, XX, XX },
|
||||
/* F2 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* F3 */ { "movdqu", 0, Vdq, Wdq, XX },
|
||||
};
|
||||
|
||||
@ -1110,7 +1110,7 @@ static BxDisasmOpcodeInfo_t BxDisasmGroupG3Eb[8] = {
|
||||
/* 0 */ { "test", 0, Eb, Ib, XX },
|
||||
/* 1 */ { "test", 0, Eb, Ib, XX },
|
||||
/* 2 */ { "not", 0, Eb, XX, XX },
|
||||
/* 3 */ { "beg", 0, Eb, XX, XX },
|
||||
/* 3 */ { "neg", 0, Eb, XX, XX },
|
||||
/* 4 */ { "mul", 0, AL, Eb, XX },
|
||||
/* 5 */ { "imul", 0, AL, Eb, XX },
|
||||
/* 6 */ { "div", 0, AL, Eb, XX },
|
||||
@ -1143,9 +1143,9 @@ static BxDisasmOpcodeInfo_t BxDisasmGroupG5[8] = {
|
||||
/* 0 */ { "inc", 0, Ev, XX, XX },
|
||||
/* 1 */ { "dec", 0, Ev, XX, XX },
|
||||
/* 2 */ { "call", 0, Ev, XX, XX },
|
||||
/* 3 */ { "callw", 0, Mp, XX, XX },
|
||||
/* 3 */ { "call far", 0, Mp, XX, XX },
|
||||
/* 4 */ { "jmp", 0, Ev, XX, XX },
|
||||
/* 5 */ { "jmpw", 0, Mp, XX, XX },
|
||||
/* 5 */ { "jmp far", 0, Mp, XX, XX },
|
||||
/* 6 */ { "push", 0, Ev, XX, XX },
|
||||
/* 7 */ { "(invalid)", 0, XX, XX, XX }
|
||||
};
|
||||
@ -1233,9 +1233,9 @@ static BxDisasmOpcodeInfo_t BxDisasmGroupG15[8] = {
|
||||
/* 2 */ { "ldmxcsr", 0, Md, XX, XX },
|
||||
/* 3 */ { "stmxcsr", 0, Md, XX, XX },
|
||||
/* 4 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* 5 */ { "lfence", 0, Mx, XX, XX },
|
||||
/* 6 */ { "mfence", 0, Mx, XX, XX },
|
||||
/* 7 */ { "sfence", 0, Mx, XX, XX } /* SFENCE/CFLUSH */
|
||||
/* 5 */ { "lfence", 0, XX, XX, XX },
|
||||
/* 6 */ { "mfence", 0, XX, XX, XX },
|
||||
/* 7 */ { "sfence", 0, XX, XX, XX } /* SFENCE/CFLUSH */
|
||||
};
|
||||
|
||||
static BxDisasmOpcodeInfo_t BxDisasmGroupG16[8] = {
|
||||
@ -1750,38 +1750,38 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* D9 FF */ { "fcos", 0, XX, XX, XX },
|
||||
|
||||
// DA (modrm is outside 00h - BFh) (mod == 11)
|
||||
/* DA C0 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C1 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C2 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C3 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C4 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C5 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C6 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C7 */ { "fcmovb", 0, STj, STj, XX },
|
||||
/* DA C8 */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA C9 */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA CA */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA CB */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA CC */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA CD */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA CE */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA CF */ { "fcmove", 0, STj, STj, XX },
|
||||
/* DA D0 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D1 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D2 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D3 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D4 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D5 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D6 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D7 */ { "fcmovbe", 0, STj, STj, XX },
|
||||
/* DA D8 */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA D9 */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA DA */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA DB */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA DC */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA DD */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA DE */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA DF */ { "fcmovu", 0, STj, STj, XX },
|
||||
/* DA C0 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C1 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C2 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C3 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C4 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C5 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C6 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C7 */ { "fcmovb", 0, ST0, STj, XX },
|
||||
/* DA C8 */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA C9 */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA CA */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA CB */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA CC */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA CD */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA CE */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA CF */ { "fcmove", 0, ST0, STj, XX },
|
||||
/* DA D0 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D1 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D2 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D3 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D4 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D5 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D6 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D7 */ { "fcmovbe", 0, ST0, STj, XX },
|
||||
/* DA D8 */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA D9 */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA DA */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA DB */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA DC */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA DD */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA DE */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA DF */ { "fcmovu", 0, ST0, STj, XX },
|
||||
/* DA E0 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DA E1 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DA E2 */ { "(invalid)", 0, XX, XX, XX },
|
||||
@ -1816,38 +1816,38 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* DA FF */ { "(invalid)", 0, XX, XX, XX },
|
||||
|
||||
// DB (modrm is outside 00h - BFh) (mod == 11)
|
||||
/* DB C0 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C1 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C2 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C3 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C4 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C5 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C6 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C7 */ { "fcmovnb", 0, STj, STj, XX },
|
||||
/* DB C8 */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB C9 */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB CA */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB CB */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB CC */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB CD */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB CE */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB CF */ { "fcmovne", 0, STj, STj, XX },
|
||||
/* DB D0 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D1 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D2 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D3 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D4 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D5 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D6 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D7 */ { "fcmovnbe", 0, STj, STj, XX },
|
||||
/* DB D8 */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB D9 */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB DA */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB DB */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB DC */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB DD */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB DE */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB DF */ { "fcmovnu", 0, STj, STj, XX },
|
||||
/* DB C0 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C1 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C2 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C3 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C4 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C5 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C6 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C7 */ { "fcmovnb", 0, ST0, STj, XX },
|
||||
/* DB C8 */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB C9 */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB CA */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB CB */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB CC */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB CD */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB CE */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB CF */ { "fcmovne", 0, ST0, STj, XX },
|
||||
/* DB D0 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D1 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D2 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D3 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D4 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D5 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D6 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D7 */ { "fcmovnbe", 0, ST0, STj, XX },
|
||||
/* DB D8 */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB D9 */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB DA */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB DB */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB DC */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB DD */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB DE */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB DF */ { "fcmovnu", 0, ST0, STj, XX },
|
||||
/* DB E0 */ { "feni (287 only)", 0, XX, XX, XX },
|
||||
/* DB E1 */ { "fdisi (287 only)", 0, XX, XX, XX },
|
||||
/* DB E2 */ { "fnclex", 0, XX, XX, XX },
|
||||
@ -1882,22 +1882,22 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* DB FF */ { "(invalid)", 0, XX, XX, XX },
|
||||
|
||||
// DC (modrm is outside 00h - BFh) (mod == 11)
|
||||
/* DC C0 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C1 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C2 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C3 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C4 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C5 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C6 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C7 */ { "fadd", 0, STj, STj, XX },
|
||||
/* DC C8 */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC C9 */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC CA */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC CB */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC CC */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC CD */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC CE */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC CF */ { "fmul", 0, STj, STj, XX },
|
||||
/* DC C0 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C1 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C2 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C3 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C4 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C5 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C6 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C7 */ { "fadd", 0, STj, ST0, XX },
|
||||
/* DC C8 */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC C9 */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC CA */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC CB */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC CC */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC CD */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC CE */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC CF */ { "fmul", 0, STj, ST0, XX },
|
||||
/* DC D0 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DC D1 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DC D2 */ { "(invalid)", 0, XX, XX, XX },
|
||||
@ -1914,38 +1914,38 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* DC DD */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DC DE */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DC DF */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DC E0 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E1 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E2 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E3 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E4 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E5 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E6 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E7 */ { "fsubr", 0, STj, STj, XX },
|
||||
/* DC E8 */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC E9 */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC EA */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC EB */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC EC */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC ED */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC EE */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC EF */ { "fsub", 0, STj, STj, XX },
|
||||
/* DC F0 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F1 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F2 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F3 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F4 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F5 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F6 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F7 */ { "fdivr", 0, STj, STj, XX },
|
||||
/* DC F8 */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC F9 */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC FA */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC FB */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC FC */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC FD */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC FE */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC FF */ { "fdiv", 0, STj, STj, XX },
|
||||
/* DC E0 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E1 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E2 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E3 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E4 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E5 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E6 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E7 */ { "fsubr", 0, STj, ST0, XX },
|
||||
/* DC E8 */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC E9 */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC EA */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC EB */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC EC */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC ED */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC EE */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC EF */ { "fsub", 0, STj, ST0, XX },
|
||||
/* DC F0 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F1 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F2 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F3 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F4 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F5 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F6 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F7 */ { "fdivr", 0, STj, ST0, XX },
|
||||
/* DC F8 */ { "fdiv", 0, STj, ST0, XX },
|
||||
/* DC F9 */ { "fdiv", 0, STj, ST0, XX },
|
||||
/* DC FA */ { "fdiv", 0, STj, ST0, XX },
|
||||
/* DC FB */ { "fdiv", 0, STj, ST0, XX },
|
||||
/* DC FC */ { "fdiv", 0, STj, ST0, XX },
|
||||
/* DC FD */ { "fdiv", 0, STj, ST0, XX },
|
||||
/* DC FE */ { "fdiv", 0, STj, ST0, XX },
|
||||
/* DC FF */ { "fdiv", 0, STj, ST0, XX },
|
||||
|
||||
// DD (modrm is outside 00h - BFh) (mod == 11)
|
||||
/* DD C0 */ { "ffree", 0, STj, XX, XX },
|
||||
@ -2014,22 +2014,22 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* DD FF */ { "(invalid)", 0, XX, XX, XX },
|
||||
|
||||
// DE (modrm is outside 00h - BFh) (mod == 11)
|
||||
/* DE C0 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C1 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C2 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C3 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C4 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C5 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C6 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C7 */ { "faddp", 0, STj, STj, XX },
|
||||
/* DE C8 */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE C9 */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE CA */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE CB */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE CC */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE CD */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE CE */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE CF */ { "fmulp", 0, STj, STj, XX },
|
||||
/* DE C0 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C1 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C2 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C3 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C4 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C5 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C6 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C7 */ { "faddp", 0, STj, ST0, XX },
|
||||
/* DE C8 */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE C9 */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE CA */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE CB */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE CC */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE CD */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE CE */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE CF */ { "fmulp", 0, STj, ST0, XX },
|
||||
/* DE D0 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DE D1 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DE D2 */ { "(invalid)", 0, XX, XX, XX },
|
||||
@ -2046,38 +2046,38 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* DE DD */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DE DE */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DE DF */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DE E0 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E1 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E2 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E3 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E4 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E5 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E6 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E7 */ { "fsubrp", 0, STj, STj, XX },
|
||||
/* DE E8 */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE E9 */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE EA */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE EB */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE EC */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE ED */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE EE */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE EF */ { "fsubp", 0, STj, STj, XX },
|
||||
/* DE F0 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F1 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F2 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F3 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F4 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F5 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F6 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F7 */ { "fdivrp", 0, STj, STj, XX },
|
||||
/* DE F8 */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE F9 */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE FA */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE FB */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE FC */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE FD */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE FE */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE FF */ { "fdivp", 0, STj, STj, XX },
|
||||
/* DE E0 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E1 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E2 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E3 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E4 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E5 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E6 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E7 */ { "fsubrp", 0, STj, ST0, XX },
|
||||
/* DE E8 */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE E9 */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE EA */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE EB */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE EC */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE ED */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE EE */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE EF */ { "fsubp", 0, STj, ST0, XX },
|
||||
/* DE F0 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F1 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F2 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F3 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F4 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F5 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F6 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F7 */ { "fdivrp", 0, STj, ST0, XX },
|
||||
/* DE F8 */ { "fdivp", 0, STj, ST0, XX },
|
||||
/* DE F9 */ { "fdivp", 0, STj, ST0, XX },
|
||||
/* DE FA */ { "fdivp", 0, STj, ST0, XX },
|
||||
/* DE FB */ { "fdivp", 0, STj, ST0, XX },
|
||||
/* DE FC */ { "fdivp", 0, STj, ST0, XX },
|
||||
/* DE FD */ { "fdivp", 0, STj, ST0, XX },
|
||||
/* DE FE */ { "fdivp", 0, STj, ST0, XX },
|
||||
/* DE FF */ { "fdivp", 0, STj, ST0, XX },
|
||||
|
||||
// DF (modrm is outside 00h - BFh) (mod == 11)
|
||||
/* DF C0 */ { "ffreep", 0, STj, XX, XX }, // 287+ compatibility opcode
|
||||
@ -2120,22 +2120,22 @@ static BxDisasmOpcodeInfo_t BxDisasmOpcodeInfoFP[512] = {
|
||||
/* DF E5 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DF E6 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DF E7 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DF E8 */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF E9 */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF EA */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF EB */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF EC */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF ED */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF EE */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF EF */ { "fucomip", 0, STj, STj, XX },
|
||||
/* DF F0 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF F1 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF F2 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF F3 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF F4 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF F5 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF F6 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF F7 */ { "fcomip", 0, STj, STj, XX },
|
||||
/* DF E8 */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF E9 */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF EA */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF EB */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF EC */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF ED */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF EE */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF EF */ { "fucomip", 0, ST0, STj, XX },
|
||||
/* DF F0 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F1 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F2 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F3 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F4 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F5 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F6 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F7 */ { "fcomip", 0, ST0, STj, XX },
|
||||
/* DF F8 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DF F9 */ { "(invalid)", 0, XX, XX, XX },
|
||||
/* DF FA */ { "(invalid)", 0, XX, XX, XX },
|
||||
|
@ -22,18 +22,17 @@
|
||||
}
|
||||
|
||||
// will be used in future
|
||||
#define IF_8086 0x00000000 /* 8086 instruction */
|
||||
#define IF_186 0x00000000 /* 186+ instruction */
|
||||
#define IF_286 0x00000000 /* 286+ instruction */
|
||||
#define IF_386 0x00000000 /* 386+ instruction */
|
||||
#define IF_387 0x00000000 /* 387+ FPU instruction */
|
||||
#define IF_486 0x00000000 /* 486+ instruction */
|
||||
#define IF_PENTIUM 0x00000000 /* Pentium instruction */
|
||||
#define IF_P6 0x00000000 /* P6 instruction */
|
||||
#define IF_KATMAI 0x00000000 /* Katmai instruction */
|
||||
#define IF_WILLAMETTE 0x00000000 /* Willamette instruction */
|
||||
#define IF_PRESCOTT 0x00000000 /* Prescott instruction */
|
||||
#define IF_X86_64 0x00000000 /* x86-64 specific instruction */
|
||||
#define IA_8086 0x00000000 /* 8086 instruction */
|
||||
#define IA_286 0x00000000 /* 286+ instruction */
|
||||
#define IA_386 0x00000000 /* 386+ instruction */
|
||||
#define IA_FPU 0x00000000
|
||||
#define IA_486 0x00000000 /* 486+ instruction */
|
||||
#define IA_PENTIUM 0x00000000 /* Pentium instruction */
|
||||
#define IA_P6 0x00000000 /* P6 instruction */
|
||||
#define IA_KATMAI 0x00000000 /* Katmai instruction */
|
||||
#define IA_WILLAMETTE 0x00000000 /* Willamette instruction */
|
||||
#define IA_PRESCOTT 0x00000000 /* Prescott instruction */
|
||||
#define IA_X86_64 0x00000000 /* x86-64 specific instruction */
|
||||
|
||||
#define IF_ARITHMETIC 0x00000000 /* arithmetic instruction */
|
||||
#define IF_LOGIC 0x00000000 /* logic instruction */
|
||||
@ -101,8 +100,6 @@ enum {
|
||||
#define P_MODE 0x8
|
||||
#define S_MODE 0x9
|
||||
|
||||
#define ES_SEG 0x80
|
||||
|
||||
class disassembler;
|
||||
|
||||
typedef void (disassembler::*BxDisasmPtr_t) (unsigned attr);
|
||||
@ -110,18 +107,41 @@ typedef void (disassembler::*BxDisasmResolveModrmPtr_t) (unsigned attr);
|
||||
|
||||
class disassembler {
|
||||
public:
|
||||
disassembler() {}
|
||||
disassembler() { set_syntax_intel(); }
|
||||
unsigned disasm(bx_bool is_32, Bit32u base, Bit32u ip, Bit8u *instr, char *disbuf);
|
||||
|
||||
void set_syntax_att();
|
||||
void set_syntax_intel();
|
||||
|
||||
private:
|
||||
bx_bool intel_mode;
|
||||
|
||||
const char **general_16bit_reg_name;
|
||||
const char **general_8bit_reg_name;
|
||||
const char **general_32bit_reg_name;
|
||||
|
||||
const char **segment_name;
|
||||
|
||||
const char **index16;
|
||||
const char **index_name32;
|
||||
|
||||
const char *sreg_mod01or10_rm32[8];
|
||||
|
||||
const char *sreg_mod00_base32[8];
|
||||
const char *sreg_mod01or10_base32[8];
|
||||
|
||||
const char *sreg_mod00_rm16[8];
|
||||
const char *sreg_mod01or10_rm16[8];
|
||||
|
||||
private:
|
||||
|
||||
bx_bool i32bit_opsize;
|
||||
bx_bool i32bit_addrsize;
|
||||
|
||||
Bit8u modrm, mod, nnn, rm;
|
||||
Bit8u sib, scale, index, base;
|
||||
Bit8u sib, scale, sib_index, sib_base;
|
||||
|
||||
union {
|
||||
Bit8u displ8;
|
||||
Bit16u displ16;
|
||||
Bit32u displ32;
|
||||
} displacement;
|
||||
@ -170,6 +190,24 @@ private:
|
||||
void dis_sprintf(char *fmt, ...);
|
||||
void decode_modrm();
|
||||
|
||||
void resolve16_mod0 (unsigned mode);
|
||||
void resolve16_mod1or2 (unsigned mode);
|
||||
|
||||
void resolve32_mod0 (unsigned mode);
|
||||
void resolve32_mod1or2 (unsigned mode);
|
||||
|
||||
void resolve32_mod0_rm4 (unsigned mode);
|
||||
void resolve32_mod1or2_rm4 (unsigned mode);
|
||||
|
||||
void initialize_modrm_segregs();
|
||||
|
||||
void print_datasize (unsigned mode);
|
||||
|
||||
void print_memory_access16(int datasize,
|
||||
const char *seg, const char *index, Bit16u disp);
|
||||
void print_memory_access32(int datasize,
|
||||
const char *seg, const char *base, const char *index, int scale, Bit32u disp);
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
@ -213,7 +251,7 @@ public:
|
||||
* register and any of the following values: a base register, an
|
||||
* index register, a scaling factor, and a displacement.
|
||||
* X - Memory addressed by the DS:rSI register pair.
|
||||
* Y - Memory addressed by the ES:rDI register pair.
|
||||
* Y - Memory addressed by the DS:rDI register pair.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -243,18 +281,18 @@ public:
|
||||
void XX (unsigned) {}
|
||||
|
||||
// fpu
|
||||
void ST0 (unsigned) { dis_sprintf("st(0)"); }
|
||||
void ST0 (unsigned);
|
||||
void STj (unsigned);
|
||||
|
||||
// general/segment register
|
||||
void Rd (unsigned);
|
||||
void Rw (unsigned);
|
||||
void Rd (unsigned);
|
||||
void Sw (unsigned);
|
||||
|
||||
// control/debug register
|
||||
void Cd (unsigned) { dis_sprintf("cr%d", nnn); }
|
||||
void Dd (unsigned) { dis_sprintf("db%d", nnn); }
|
||||
void Td (unsigned) { dis_sprintf("tr%d", nnn); }
|
||||
void Cd (unsigned);
|
||||
void Dd (unsigned);
|
||||
void Td (unsigned);
|
||||
|
||||
// segment register (implicit)
|
||||
void OP_SEG (unsigned);
|
||||
@ -271,6 +309,10 @@ public:
|
||||
void OP_X (unsigned);
|
||||
void OP_Y (unsigned);
|
||||
|
||||
// string instructions (ES based)
|
||||
void OP_Xe(unsigned);
|
||||
void OP_Ye(unsigned);
|
||||
|
||||
// mmx/xmm
|
||||
void OP_P (unsigned);
|
||||
void OP_Q (unsigned);
|
||||
@ -278,7 +320,7 @@ public:
|
||||
void OP_V (unsigned);
|
||||
|
||||
// immediate
|
||||
void I1 (unsigned) { dis_sprintf("1"); }
|
||||
void I1 (unsigned);
|
||||
void Ib (unsigned);
|
||||
void Iw (unsigned);
|
||||
void Id (unsigned);
|
||||
@ -305,23 +347,6 @@ public:
|
||||
// jump
|
||||
void Jb (unsigned);
|
||||
void Jv (unsigned);
|
||||
|
||||
private:
|
||||
|
||||
void resolve16_mod0 (unsigned mode);
|
||||
void resolve16_mod1 (unsigned mode);
|
||||
void resolve16_mod2 (unsigned mode);
|
||||
|
||||
void resolve32_mod0 (unsigned mode);
|
||||
void resolve32_mod1 (unsigned mode);
|
||||
void resolve32_mod2 (unsigned mode);
|
||||
|
||||
void resolve32_mod0_rm4 (unsigned mode);
|
||||
void resolve32_mod1_rm4 (unsigned mode);
|
||||
void resolve32_mod2_rm4 (unsigned mode);
|
||||
|
||||
void print_datasize (unsigned mode);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,55 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include "disasm.h"
|
||||
|
||||
extern const char *general_16bit_reg_name[8];
|
||||
extern const char *general_32bit_reg_name[8];
|
||||
|
||||
static const char *sreg_mod01_rm32[8] = {
|
||||
"ds", "ds", "ds", "ds", "??", "ss", "ds", "ds"
|
||||
};
|
||||
|
||||
static const char *sreg_mod10_rm32[8] = {
|
||||
"ds", "ds", "ds", "ds", "??", "ss", "ds", "ds"
|
||||
};
|
||||
|
||||
static const char *sreg_mod00_base32[8] = {
|
||||
"ds", "ds", "ds", "ds", "ss", "ds", "ds", "ds"
|
||||
};
|
||||
|
||||
static const char *sreg_mod01_base32[8] = {
|
||||
"ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds"
|
||||
};
|
||||
|
||||
static const char *sreg_mod10_base32[8] = {
|
||||
"ds", "ds", "ds", "ds", "ss", "ss", "ds", "ds"
|
||||
};
|
||||
|
||||
static const char *sreg_mod00_rm16[8] = {
|
||||
"ds", "ds", "ss", "ss", "ds", "ds", "ds", "ds"
|
||||
};
|
||||
|
||||
static const char *sreg_mod01_rm16[8] = {
|
||||
"ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds"
|
||||
};
|
||||
|
||||
static const char *sreg_mod10_rm16[8] = {
|
||||
"ds", "ds", "ss", "ss", "ds", "ds", "ss", "ds"
|
||||
};
|
||||
|
||||
static const char *intel_index16[8] = {
|
||||
"bx+si",
|
||||
"bx+di",
|
||||
"bp+si",
|
||||
"bp+di",
|
||||
"si",
|
||||
"di",
|
||||
"bp",
|
||||
"bx"
|
||||
};
|
||||
|
||||
static const char *index_name32[8] = {
|
||||
"eax", "ecx", "edx", "ebx", "???", "ebp", "esi", "edi"
|
||||
};
|
||||
|
||||
void disassembler::decode_modrm()
|
||||
{
|
||||
modrm = fetch_byte();
|
||||
@ -74,32 +25,32 @@ void disassembler::decode_modrm()
|
||||
break;
|
||||
case 1:
|
||||
/* reg, 8-bit displacement, sign extend */
|
||||
resolve_modrm = &disassembler::resolve32_mod1;
|
||||
resolve_modrm = &disassembler::resolve32_mod1or2;
|
||||
displacement.displ32 = (Bit8s) fetch_byte();
|
||||
break;
|
||||
case 2:
|
||||
/* reg, 32-bit displacement */
|
||||
resolve_modrm = &disassembler::resolve32_mod2;
|
||||
resolve_modrm = &disassembler::resolve32_mod1or2;
|
||||
displacement.displ32 = fetch_dword();
|
||||
break;
|
||||
} /* switch (mod) */
|
||||
} /* if (rm != 4) */
|
||||
else { /* rm == 4, s-i-b byte follows */
|
||||
sib = fetch_byte();
|
||||
BX_DECODE_SIB(sib, scale, index, base);
|
||||
BX_DECODE_SIB(sib, scale, sib_index, sib_base);
|
||||
|
||||
switch (mod) {
|
||||
case 0:
|
||||
resolve_modrm = &disassembler::resolve32_mod0_rm4;
|
||||
if (base == 5)
|
||||
if (sib_base == 5)
|
||||
displacement.displ32 = fetch_dword();
|
||||
break;
|
||||
case 1:
|
||||
resolve_modrm = &disassembler::resolve32_mod1_rm4;
|
||||
displacement.displ8 = fetch_byte();
|
||||
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
|
||||
displacement.displ32 = (Bit8s) fetch_byte();
|
||||
break;
|
||||
case 2:
|
||||
resolve_modrm = &disassembler::resolve32_mod2_rm4;
|
||||
resolve_modrm = &disassembler::resolve32_mod1or2_rm4;
|
||||
displacement.displ32 = fetch_dword();
|
||||
break;
|
||||
}
|
||||
@ -116,11 +67,11 @@ void disassembler::decode_modrm()
|
||||
break;
|
||||
case 1:
|
||||
/* reg, 8-bit displacement, sign extend */
|
||||
resolve_modrm = &disassembler::resolve16_mod1;
|
||||
resolve_modrm = &disassembler::resolve16_mod1or2;
|
||||
displacement.displ16 = (Bit8s) fetch_byte();
|
||||
break;
|
||||
case 2:
|
||||
resolve_modrm = &disassembler::resolve16_mod2;
|
||||
resolve_modrm = &disassembler::resolve16_mod1or2;
|
||||
displacement.displ16 = fetch_word();
|
||||
break;
|
||||
case 3:
|
||||
@ -131,6 +82,103 @@ void disassembler::decode_modrm()
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::resolve16_mod0(unsigned mode)
|
||||
{
|
||||
const char *seg;
|
||||
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = sreg_mod00_rm16[rm];
|
||||
|
||||
if(rm == 6)
|
||||
print_memory_access16(mode, seg, NULL, displacement.displ16);
|
||||
else
|
||||
print_memory_access16(mode, seg, index16[rm], 0);
|
||||
}
|
||||
|
||||
void disassembler::resolve16_mod1or2(unsigned mode)
|
||||
{
|
||||
const char *seg;
|
||||
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = sreg_mod01or10_rm16[rm];
|
||||
|
||||
print_memory_access16(mode, seg, index16[rm], displacement.displ16);
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod0(unsigned mode)
|
||||
{
|
||||
const char *seg;
|
||||
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = segment_name[DS_REG];
|
||||
|
||||
if (rm == 5) /* no reg, 32-bit displacement */
|
||||
print_memory_access32(mode, seg, NULL, NULL, 0, displacement.displ32);
|
||||
else
|
||||
print_memory_access32(mode, seg, general_32bit_reg_name[rm], NULL, 0, 0);
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod1or2(unsigned mode)
|
||||
{
|
||||
const char *seg;
|
||||
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = sreg_mod01or10_rm32[rm];
|
||||
|
||||
print_memory_access32(mode, seg,
|
||||
general_32bit_reg_name[rm], NULL, 0, displacement.displ32);
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod0_rm4(unsigned mode)
|
||||
{
|
||||
const char *seg, *base = NULL, *index = NULL;
|
||||
Bit32u disp32 = 0;
|
||||
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = sreg_mod00_base32[sib_base];
|
||||
|
||||
if (sib_base != 5)
|
||||
base = general_32bit_reg_name[sib_base];
|
||||
|
||||
if (sib_index != 4)
|
||||
{
|
||||
index = index_name32[sib_index];
|
||||
}
|
||||
|
||||
if (sib_base == 5)
|
||||
disp32 = displacement.displ32;
|
||||
|
||||
print_memory_access32(mode, seg, base, index, scale, disp32);
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod1or2_rm4(unsigned mode)
|
||||
{
|
||||
const char *seg, *index = NULL;
|
||||
|
||||
if (seg_override)
|
||||
seg = seg_override;
|
||||
else
|
||||
seg = sreg_mod01or10_base32[sib_base];
|
||||
|
||||
if (sib_index != 4)
|
||||
{
|
||||
index = index_name32[sib_index];
|
||||
}
|
||||
|
||||
print_memory_access32(mode, seg,
|
||||
general_32bit_reg_name[sib_base], index, scale, displacement.displ32);
|
||||
}
|
||||
|
||||
void disassembler::print_datasize(unsigned mode)
|
||||
{
|
||||
switch(mode)
|
||||
@ -154,13 +202,12 @@ void disassembler::print_datasize(unsigned mode)
|
||||
dis_sprintf("qword ptr ");
|
||||
break;
|
||||
case O_MODE:
|
||||
dis_sprintf("oword ptr ");
|
||||
dis_sprintf("dqword ptr ");
|
||||
break;
|
||||
case T_MODE:
|
||||
dis_sprintf("tword ptr ");
|
||||
dis_sprintf("tbyte ptr ");
|
||||
break;
|
||||
case P_MODE:
|
||||
// ???
|
||||
break;
|
||||
case S_MODE:
|
||||
break;
|
||||
@ -169,212 +216,132 @@ void disassembler::print_datasize(unsigned mode)
|
||||
};
|
||||
}
|
||||
|
||||
void disassembler::resolve16_mod0(unsigned mode)
|
||||
void disassembler::print_memory_access16(int datasize,
|
||||
const char *seg, const char *index, Bit16u disp)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
print_datasize(datasize);
|
||||
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod00_rm16[rm];
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
if(rm == 6)
|
||||
if (intel_mode)
|
||||
{
|
||||
dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, (unsigned) displacement.displ16);
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s]", seg, index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]);
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:0x%x(%s,1)", seg, (unsigned) disp, index);
|
||||
else
|
||||
dis_sprintf("%s:(%s,1)", seg, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::resolve16_mod1(unsigned mode)
|
||||
void disassembler::print_memory_access32(int datasize,
|
||||
const char *seg, const char *base, const char *index, int scale, Bit32u disp)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod01_rm16[rm];
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
if (displacement.displ16)
|
||||
{
|
||||
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
||||
intel_index16[rm], (unsigned) displacement.displ16);
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]);
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::resolve16_mod2(unsigned mode)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod10_rm16[rm];
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
if (displacement.displ16)
|
||||
{
|
||||
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
||||
intel_index16[rm], (unsigned) displacement.displ16);
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_sprintf("%s:[%s]", mod_rm_seg_reg, intel_index16[rm]);
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod0(unsigned mode)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = "ds";
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
if (rm == 5) { /* no reg, 32-bit displacement */
|
||||
dis_sprintf("[%s:0x%x]", mod_rm_seg_reg, displacement.displ32);
|
||||
}
|
||||
else {
|
||||
dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]);
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod1(unsigned mode)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod01_rm32[rm];
|
||||
|
||||
print_datasize(mode);
|
||||
print_datasize(datasize);
|
||||
|
||||
/* reg, 8-bit displacement, sign extend */
|
||||
if (displacement.displ32)
|
||||
if (intel_mode)
|
||||
{
|
||||
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
||||
general_32bit_reg_name[rm], (unsigned) displacement.displ32);
|
||||
if (base == NULL)
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scale != 0)
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:[%s*%d+0x%x]", seg, index, 1<<scale, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s*%d]", seg, index, 1<<scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:[%s+0x%x]", seg, index, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s]", seg, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:[%s+0x%x]", seg, base, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s]", seg, base);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scale != 0)
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:[%s+%s*%d+0x%x]", seg, base, index, 1<<scale, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s+%s*%d]", seg, base, index, 1<<scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:[%s+%s+0x%x]", seg, base, index, (unsigned) disp);
|
||||
else
|
||||
dis_sprintf("%s:[%s+%s]", seg, base, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]);
|
||||
if (base == NULL)
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
dis_sprintf("%s:0x%x", seg, (unsigned) disp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:0x%x(,%s,%d)", seg, (unsigned) disp, index, 1<<scale);
|
||||
else
|
||||
dis_sprintf("%s:(,%s,%d)", seg, index, 1<<scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index == NULL)
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:0x%x(%s)", seg, (unsigned) disp, base);
|
||||
else
|
||||
dis_sprintf("%s:[%s]", seg, base);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (disp != 0)
|
||||
dis_sprintf("%s:0x%x(%s,%s,%d)", seg, (unsigned) disp, base, index, 1<<scale);
|
||||
else
|
||||
dis_sprintf("%s:(%s,%s,%d)", seg, base, index, 1<<scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod2(unsigned mode)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod10_rm32[rm];
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
/* reg, 32-bit displacement */
|
||||
if (displacement.displ32)
|
||||
{
|
||||
dis_sprintf("%s:[%s+0x%x]", mod_rm_seg_reg,
|
||||
general_32bit_reg_name[rm], (unsigned) displacement.displ32);
|
||||
}
|
||||
else
|
||||
{
|
||||
dis_sprintf("%s:[%s]", mod_rm_seg_reg, general_32bit_reg_name[rm]);
|
||||
}
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod0_rm4(unsigned mode)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod00_base32[base];
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
dis_sprintf("%s:[", mod_rm_seg_reg);
|
||||
if (base != 5)
|
||||
dis_sprintf("%s+", general_32bit_reg_name[base]);
|
||||
|
||||
if (index != 4)
|
||||
{
|
||||
dis_sprintf("%s", index_name32[index]);
|
||||
if (scale)
|
||||
dis_sprintf("*%u", 1 << scale);
|
||||
if (base == 5) dis_sprintf("+");
|
||||
}
|
||||
|
||||
if (base == 5)
|
||||
dis_sprintf("0x%x", (unsigned) displacement.displ32);
|
||||
|
||||
dis_sprintf("]");
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod1_rm4(unsigned mode)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod01_base32[base];
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]);
|
||||
|
||||
if (index != 4)
|
||||
{
|
||||
dis_sprintf("+%s", index_name32[index]);
|
||||
if (scale)
|
||||
dis_sprintf("*%u", 1 << scale);
|
||||
}
|
||||
|
||||
if (displacement.displ8)
|
||||
dis_sprintf("+0x%x", (unsigned) displacement.displ8);
|
||||
|
||||
dis_sprintf("]");
|
||||
}
|
||||
|
||||
void disassembler::resolve32_mod2_rm4(unsigned mode)
|
||||
{
|
||||
const char *mod_rm_seg_reg;
|
||||
if (seg_override)
|
||||
mod_rm_seg_reg = seg_override;
|
||||
else
|
||||
mod_rm_seg_reg = sreg_mod10_base32[base];
|
||||
|
||||
print_datasize(mode);
|
||||
|
||||
dis_sprintf("%s:[%s", mod_rm_seg_reg, general_32bit_reg_name[base]);
|
||||
|
||||
if (index != 4)
|
||||
{
|
||||
dis_sprintf("+%s", index_name32[index]);
|
||||
if (scale)
|
||||
dis_sprintf("*%u", 1 << scale);
|
||||
}
|
||||
|
||||
if (displacement.displ32)
|
||||
dis_sprintf("+0x%x", (unsigned) displacement.displ32);
|
||||
|
||||
dis_sprintf("]");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user