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:
Stanislav Shwartsman 2004-12-08 18:54:15 +00:00
parent 5a36efedfa
commit 9d1b401512
7 changed files with 667 additions and 590 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 },

View File

@ -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

View File

@ -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("]");
}