2009-10-15 00:45:29 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2010-03-26 13:39:40 +03:00
|
|
|
// $Id: disasm.h,v 1.59 2010-03-26 10:39:40 sshwarts Exp $
|
2009-10-15 00:45:29 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Copyright (c) 2005-2009 Stanislav Shwartsman
|
|
|
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2003-12-24 23:32:59 +03:00
|
|
|
#ifndef _BX_DISASM_H_
|
|
|
|
#define _BX_DISASM_H_
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#define BX_DECODE_MODRM(modrm_byte, mod, opcode, rm) { \
|
|
|
|
mod = (modrm_byte >> 6) & 0x03; \
|
|
|
|
opcode = (modrm_byte >> 3) & 0x07; \
|
|
|
|
rm = modrm_byte & 0x07; \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define BX_DECODE_SIB(sib_byte, scale, index, base) { \
|
2005-12-23 17:15:13 +03:00
|
|
|
scale = sib_byte >> 6; \
|
|
|
|
index = (sib_byte >> 3) & 0x07; \
|
|
|
|
base = sib_byte & 0x07; \
|
2003-12-24 23:32:59 +03:00
|
|
|
}
|
|
|
|
|
2010-02-24 22:27:51 +03:00
|
|
|
/* Instruction set attributes (duplicated in cpu.h) */
|
|
|
|
#define IA_X87 0x00000001 /* FPU (X87) instruction */
|
|
|
|
#define IA_486 0x00000002 /* 486 new instruction */
|
|
|
|
#define IA_PENTIUM 0x00000004 /* Pentium new instruction */
|
|
|
|
#define IA_P6 0x00000008 /* P6 new instruction */
|
2008-05-25 19:42:26 +04:00
|
|
|
#define IA_MMX 0x00000010 /* MMX instruction */
|
|
|
|
#define IA_3DNOW 0x00000020 /* 3DNow! instruction */
|
2010-02-24 22:27:51 +03:00
|
|
|
#define IA_MONITOR_MWAIT 0x00000040 /* MONITOR/MWAIT instruction */
|
|
|
|
#define IA_CLFLUSH 0x00000080 /* CLFLUSH instruction */
|
|
|
|
#define IA_SSE 0x00000100 /* SSE instruction */
|
|
|
|
#define IA_SSE2 0x00000200 /* SSE2 instruction */
|
|
|
|
#define IA_SSE3 0x00000400 /* SSE3 instruction */
|
|
|
|
#define IA_SSSE3 0x00000800 /* SSSE3 instruction */
|
|
|
|
#define IA_SSE4_1 0x00001000 /* SSE4_1 instruction */
|
|
|
|
#define IA_SSE4_2 0x00002000 /* SSE4_2 instruction */
|
|
|
|
#define IA_SSE4A 0x00004000 /* SSE4A instruction */
|
|
|
|
#define IA_SYSENTER_SYSEXIT 0x00008000 /* SYSENTER/SYSEXIT instruction */
|
|
|
|
#define IA_VMX 0x00010000 /* VMX instruction */
|
|
|
|
#define IA_SMX 0x00020000 /* SMX instruction */
|
|
|
|
#define IA_SVM 0x00040000 /* SVM instruction */
|
|
|
|
#define IA_XSAVE 0x00080000 /* XSAVE/XRSTOR extensions instruction */
|
|
|
|
#define IA_AES 0x00100000 /* AES instruction */
|
|
|
|
#define IA_PCLMULQDQ 0x00200000 /* PCLMULQDQ instruction */
|
|
|
|
#define IA_MOVBE 0x00400000 /* MOVBE Intel Atom(R) instruction */
|
|
|
|
#define IA_AVX 0x00800000 /* AVX instruction */
|
|
|
|
#define IA_AVX_FMA 0x01000000 /* AVX FMA instruction */
|
|
|
|
#define IA_X86_64 0x02000000 /* x86-64 instruction */
|
2003-12-24 23:32:59 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
/* general purpose bit register */
|
2004-12-10 17:04:57 +03:00
|
|
|
enum {
|
|
|
|
rAX_REG,
|
|
|
|
rCX_REG,
|
|
|
|
rDX_REG,
|
|
|
|
rBX_REG,
|
|
|
|
rSP_REG,
|
|
|
|
rBP_REG,
|
|
|
|
rSI_REG,
|
|
|
|
rDI_REG
|
|
|
|
};
|
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
/* segment register */
|
2003-12-24 23:32:59 +03:00
|
|
|
enum {
|
|
|
|
ES_REG,
|
|
|
|
CS_REG,
|
|
|
|
SS_REG,
|
|
|
|
DS_REG,
|
|
|
|
FS_REG,
|
2005-12-23 17:15:13 +03:00
|
|
|
GS_REG,
|
|
|
|
INVALID_SEG1,
|
|
|
|
INVALID_SEG2
|
2003-12-24 23:32:59 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
class disassembler;
|
2006-01-28 17:48:40 +03:00
|
|
|
struct x86_insn;
|
2003-12-24 23:32:59 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
typedef void (disassembler::*BxDisasmPtr_t)(const x86_insn *insn);
|
|
|
|
typedef void (disassembler::*BxDisasmResolveModrmPtr_t)(const x86_insn *insn, unsigned attr);
|
2003-12-24 23:32:59 +03:00
|
|
|
|
2004-12-10 17:04:57 +03:00
|
|
|
struct BxDisasmOpcodeInfo_t
|
|
|
|
{
|
2005-12-23 17:15:13 +03:00
|
|
|
const char *IntelOpcode;
|
|
|
|
const char *AttOpcode;
|
2004-12-10 17:04:57 +03:00
|
|
|
BxDisasmPtr_t Operand1;
|
|
|
|
BxDisasmPtr_t Operand2;
|
|
|
|
BxDisasmPtr_t Operand3;
|
2007-10-10 00:24:42 +04:00
|
|
|
BxDisasmPtr_t Operand4;
|
2007-04-02 14:47:48 +04:00
|
|
|
Bit32u Attr;
|
2005-12-23 17:15:13 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BxDisasmOpcodeTable_t
|
|
|
|
{
|
|
|
|
Bit32u Attr;
|
|
|
|
const void *OpcodeInfo;
|
2004-12-10 17:04:57 +03:00
|
|
|
};
|
|
|
|
|
2006-01-31 20:42:31 +03:00
|
|
|
// segment override not used
|
|
|
|
#define NO_SEG_OVERRIDE 0xFF
|
|
|
|
|
2004-12-10 17:04:57 +03:00
|
|
|
// datasize attributes
|
|
|
|
#define X_SIZE 0x0000
|
|
|
|
#define B_SIZE 0x0100
|
|
|
|
#define W_SIZE 0x0200
|
|
|
|
#define D_SIZE 0x0300
|
2005-12-23 17:15:13 +03:00
|
|
|
#define Q_SIZE 0x0400
|
|
|
|
#define Z_SIZE 0x0500
|
|
|
|
#define V_SIZE 0x0600
|
2004-12-13 01:12:43 +03:00
|
|
|
#define O_SIZE 0x0700
|
|
|
|
#define T_SIZE 0x0800
|
|
|
|
#define P_SIZE 0x0900
|
2004-12-10 17:04:57 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
// branch hint attribute
|
2004-12-10 17:04:57 +03:00
|
|
|
#define BRANCH_HINT 0x1000
|
|
|
|
|
2008-02-06 01:33:35 +03:00
|
|
|
struct x86_insn
|
2005-12-23 17:15:13 +03:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
x86_insn(bx_bool is32, bx_bool is64);
|
|
|
|
|
2008-02-06 01:33:35 +03:00
|
|
|
bx_bool is_seg_override() const {
|
2006-01-31 20:42:31 +03:00
|
|
|
return (seg_override != NO_SEG_OVERRIDE);
|
|
|
|
}
|
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
public:
|
|
|
|
bx_bool is_32, is_64;
|
|
|
|
bx_bool as_32, as_64;
|
|
|
|
bx_bool os_32, os_64;
|
|
|
|
|
|
|
|
Bit8u extend8b;
|
|
|
|
Bit8u rex_r, rex_x, rex_b;
|
|
|
|
Bit8u seg_override;
|
2009-05-15 22:47:34 +04:00
|
|
|
unsigned b1;
|
2006-02-05 22:48:29 +03:00
|
|
|
unsigned ilen;
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
Bit8u modrm, mod, nnn, rm;
|
|
|
|
Bit8u sib, scale, index, base;
|
|
|
|
union {
|
|
|
|
Bit16u displ16;
|
|
|
|
Bit32u displ32;
|
|
|
|
} displacement;
|
|
|
|
};
|
|
|
|
|
|
|
|
BX_CPP_INLINE x86_insn::x86_insn(bx_bool is32, bx_bool is64)
|
|
|
|
{
|
|
|
|
is_32 = is32;
|
|
|
|
is_64 = is64;
|
|
|
|
|
|
|
|
if (is_64) {
|
|
|
|
os_64 = 0;
|
|
|
|
as_64 = 1;
|
|
|
|
os_32 = 1;
|
|
|
|
as_32 = 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
os_64 = 0;
|
|
|
|
as_64 = 0;
|
|
|
|
os_32 = is_32;
|
|
|
|
as_32 = is_32;
|
|
|
|
}
|
|
|
|
|
|
|
|
extend8b = 0;
|
|
|
|
rex_r = rex_b = rex_x = 0;
|
2006-01-31 20:42:31 +03:00
|
|
|
seg_override = NO_SEG_OVERRIDE;
|
2006-02-05 22:48:29 +03:00
|
|
|
ilen = 0;
|
2005-12-23 17:15:13 +03:00
|
|
|
b1 = 0;
|
|
|
|
|
|
|
|
modrm = mod = nnn = rm = 0;
|
|
|
|
sib = scale = index = base = 0;
|
|
|
|
displacement.displ32 = 0;
|
|
|
|
}
|
|
|
|
|
2003-12-24 23:32:59 +03:00
|
|
|
class disassembler {
|
2001-04-10 05:04:59 +04:00
|
|
|
public:
|
2009-12-28 16:44:32 +03:00
|
|
|
disassembler(): offset_mode_hex(0) { set_syntax_intel(); }
|
2005-11-14 21:09:22 +03:00
|
|
|
|
2006-02-05 22:48:29 +03:00
|
|
|
unsigned disasm(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
|
|
|
|
|
|
|
|
unsigned disasm16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
|
|
{ return disasm(0, 0, base, ip, instr, disbuf); }
|
|
|
|
|
|
|
|
unsigned disasm32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
|
|
{ return disasm(1, 0, base, ip, instr, disbuf); }
|
|
|
|
|
|
|
|
unsigned disasm64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
|
|
{ return disasm(1, 1, base, ip, instr, disbuf); }
|
|
|
|
|
|
|
|
x86_insn decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_address ip, const Bit8u *instr, char *disbuf);
|
|
|
|
|
|
|
|
x86_insn decode16(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
|
|
{ return decode(0, 0, base, ip, instr, disbuf); }
|
|
|
|
|
|
|
|
x86_insn decode32(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
|
|
{ return decode(1, 0, base, ip, instr, disbuf); }
|
|
|
|
|
|
|
|
x86_insn decode64(bx_address base, bx_address ip, const Bit8u *instr, char *disbuf)
|
|
|
|
{ return decode(1, 1, base, ip, instr, disbuf); }
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2004-12-08 21:54:15 +03:00
|
|
|
void set_syntax_intel();
|
2009-12-28 16:44:32 +03:00
|
|
|
void set_syntax_att();
|
|
|
|
|
|
|
|
void set_offset_mode_hex(bx_bool mode) { offset_mode_hex = mode; }
|
2004-12-08 21:54:15 +03:00
|
|
|
|
2006-01-25 00:34:39 +03:00
|
|
|
void toggle_syntax_mode();
|
|
|
|
|
2004-12-08 21:54:15 +03:00
|
|
|
private:
|
2009-12-28 16:44:32 +03:00
|
|
|
bx_bool intel_mode, offset_mode_hex;
|
2004-12-08 21:54:15 +03:00
|
|
|
|
2004-12-13 01:12:43 +03:00
|
|
|
const char **general_16bit_regname;
|
|
|
|
const char **general_8bit_regname;
|
|
|
|
const char **general_32bit_regname;
|
|
|
|
const char **general_8bit_regname_rex;
|
|
|
|
const char **general_64bit_regname;
|
2004-12-08 21:54:15 +03:00
|
|
|
|
|
|
|
const char **segment_name;
|
|
|
|
const char **index16;
|
|
|
|
|
2007-11-19 00:29:17 +03:00
|
|
|
const char *sreg_mod00_base32[16];
|
|
|
|
const char *sreg_mod01or10_base32[16];
|
2004-12-08 21:54:15 +03:00
|
|
|
const char *sreg_mod00_rm16[8];
|
|
|
|
const char *sreg_mod01or10_rm16[8];
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
private:
|
2004-12-08 21:54:15 +03:00
|
|
|
|
2004-12-13 01:12:43 +03:00
|
|
|
bx_address db_eip, db_base;
|
2003-12-24 23:32:59 +03:00
|
|
|
|
2006-02-05 22:48:29 +03:00
|
|
|
const Bit8u *instruction; // for fetching of next byte of instruction
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
char *disbufptr;
|
|
|
|
|
2003-12-24 23:32:59 +03:00
|
|
|
BxDisasmResolveModrmPtr_t resolve_modrm;
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-12-24 23:32:59 +03:00
|
|
|
BX_CPP_INLINE Bit8u fetch_byte() {
|
2002-09-28 10:29:55 +04:00
|
|
|
db_eip++;
|
2001-04-10 05:04:59 +04:00
|
|
|
return(*instruction++);
|
2004-12-13 01:12:43 +03:00
|
|
|
};
|
2003-12-24 23:32:59 +03:00
|
|
|
|
|
|
|
BX_CPP_INLINE Bit8u peek_byte() {
|
2001-04-10 05:04:59 +04:00
|
|
|
return(*instruction);
|
2004-12-13 01:12:43 +03:00
|
|
|
};
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-12-24 23:32:59 +03:00
|
|
|
BX_CPP_INLINE Bit16u fetch_word() {
|
|
|
|
Bit8u b0 = * (Bit8u *) instruction++;
|
|
|
|
Bit8u b1 = * (Bit8u *) instruction++;
|
|
|
|
Bit16u ret16 = (b1<<8) | b0;
|
2002-09-28 10:29:55 +04:00
|
|
|
db_eip += 2;
|
2001-04-10 05:04:59 +04:00
|
|
|
return(ret16);
|
2004-12-13 01:12:43 +03:00
|
|
|
};
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2003-12-24 23:32:59 +03:00
|
|
|
BX_CPP_INLINE Bit32u fetch_dword() {
|
|
|
|
Bit8u b0 = * (Bit8u *) instruction++;
|
|
|
|
Bit8u b1 = * (Bit8u *) instruction++;
|
|
|
|
Bit8u b2 = * (Bit8u *) instruction++;
|
|
|
|
Bit8u b3 = * (Bit8u *) instruction++;
|
|
|
|
Bit32u ret32 = (b3<<24) | (b2<<16) | (b1<<8) | b0;
|
2002-09-28 10:29:55 +04:00
|
|
|
db_eip += 4;
|
2001-04-10 05:04:59 +04:00
|
|
|
return(ret32);
|
2004-12-13 01:12:43 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
BX_CPP_INLINE Bit64u fetch_qword() {
|
|
|
|
Bit64u d0 = fetch_dword();
|
|
|
|
Bit64u d1 = fetch_dword();
|
|
|
|
Bit64u ret64 = (d1<<32) | d0;
|
|
|
|
return(ret64);
|
|
|
|
};
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2004-12-15 20:15:43 +03:00
|
|
|
void dis_putc(char symbol);
|
2008-04-27 23:47:12 +04:00
|
|
|
void dis_sprintf(const char *fmt, ...);
|
2005-12-23 17:15:13 +03:00
|
|
|
void decode_modrm(x86_insn *insn);
|
|
|
|
|
|
|
|
void resolve16_mod0 (const x86_insn *insn, unsigned mode);
|
|
|
|
void resolve16_mod1or2(const x86_insn *insn, unsigned mode);
|
2003-12-24 23:32:59 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
void resolve32_mod0 (const x86_insn *insn, unsigned mode);
|
|
|
|
void resolve32_mod1or2(const x86_insn *insn, unsigned mode);
|
2004-12-08 21:54:15 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
void resolve32_mod0_rm4 (const x86_insn *insn, unsigned mode);
|
|
|
|
void resolve32_mod1or2_rm4(const x86_insn *insn, unsigned mode);
|
2004-12-08 21:54:15 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
void resolve64_mod0 (const x86_insn *insn, unsigned mode);
|
|
|
|
void resolve64_mod1or2(const x86_insn *insn, unsigned mode);
|
|
|
|
|
|
|
|
void resolve64_mod0_rm4 (const x86_insn *insn, unsigned mode);
|
|
|
|
void resolve64_mod1or2_rm4(const x86_insn *insn, unsigned mode);
|
2004-12-08 21:54:15 +03:00
|
|
|
|
|
|
|
void initialize_modrm_segregs();
|
|
|
|
|
2009-12-28 16:44:32 +03:00
|
|
|
void print_datasize(unsigned mode);
|
2004-12-08 21:54:15 +03:00
|
|
|
|
|
|
|
void print_memory_access16(int datasize,
|
|
|
|
const char *seg, const char *index, Bit16u disp);
|
2009-12-28 16:52:40 +03:00
|
|
|
void print_memory_access32(int datasize,
|
|
|
|
const char *seg, const char *base, const char *index, int scale, Bit32s disp);
|
|
|
|
void print_memory_access64(int datasize,
|
|
|
|
const char *seg, const char *base, const char *index, int scale, Bit32s disp);
|
2004-12-08 21:54:15 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
void print_disassembly_intel(const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
|
|
|
|
void print_disassembly_att (const x86_insn *insn, const BxDisasmOpcodeInfo_t *entry);
|
2004-12-10 17:04:57 +03:00
|
|
|
|
2003-12-24 23:32:59 +03:00
|
|
|
public:
|
|
|
|
|
2008-02-06 01:33:35 +03:00
|
|
|
/*
|
2003-12-24 23:32:59 +03:00
|
|
|
* Codes for Addressing Method:
|
|
|
|
* ---------------------------
|
2008-02-06 01:33:35 +03:00
|
|
|
* A - Direct address. The instruction has no ModR/M byte; the address
|
|
|
|
* of the operand is encoded in the instruction; and no base register,
|
2003-12-24 23:32:59 +03:00
|
|
|
* index register, or scaling factor can be applied.
|
|
|
|
* C - The reg field of the ModR/M byte selects a control register.
|
|
|
|
* D - The reg field of the ModR/M byte selects a debug register.
|
2008-02-06 01:33:35 +03:00
|
|
|
* E - A ModR/M byte follows the opcode and specifies the operand. The
|
|
|
|
* operand is either a general-purpose register or a memory address.
|
2007-04-19 20:12:21 +04:00
|
|
|
* In case of the register operand, the R/M field of the ModR/M byte
|
|
|
|
* selects a general register.
|
2004-10-18 02:05:17 +04:00
|
|
|
* F - Flags Register.
|
2003-12-24 23:32:59 +03:00
|
|
|
* G - The reg field of the ModR/M byte selects a general register.
|
2008-02-06 01:33:35 +03:00
|
|
|
* H - A ModR/M byte follows the opcode and specifies the operand. The
|
|
|
|
* operand is either a general-purpose register or a memory address.
|
|
|
|
* In case of the register operand, the reg field of the ModR/M byte
|
2007-04-19 20:12:21 +04:00
|
|
|
* selects a general register.
|
2008-02-06 01:33:35 +03:00
|
|
|
* I - Immediate data. The operand value is encoded in subsequent bytes of
|
2003-12-24 23:32:59 +03:00
|
|
|
* the instruction.
|
2008-02-06 01:33:35 +03:00
|
|
|
* J - The instruction contains a relative offset to be added to the
|
2003-12-24 23:32:59 +03:00
|
|
|
* instruction pointer register.
|
|
|
|
* M - The ModR/M byte may refer only to memory.
|
2008-02-06 01:33:35 +03:00
|
|
|
* N - The R/M field of the ModR/M byte selects a packed-quadword MMX
|
2006-02-17 16:33:05 +03:00
|
|
|
technology register.
|
2008-02-06 01:33:35 +03:00
|
|
|
* O - The instruction has no ModR/M byte; the offset of the operand is
|
|
|
|
* coded as a word or double word (depending on address size attribute)
|
|
|
|
* in the instruction. No base register, index register, or scaling
|
2003-12-24 23:32:59 +03:00
|
|
|
* factor can be applied.
|
2008-02-06 01:33:35 +03:00
|
|
|
* P - The reg field of the ModR/M byte selects a packed quadword MMX
|
2003-12-24 23:32:59 +03:00
|
|
|
* technology register.
|
2008-02-06 01:33:35 +03:00
|
|
|
* Q - A ModR/M byte follows the opcode and specifies the operand. The
|
|
|
|
* operand is either an MMX technology register or a memory address.
|
|
|
|
* If it is a memory address, the address is computed from a segment
|
|
|
|
* register and any of the following values: a base register, an
|
2003-12-24 23:32:59 +03:00
|
|
|
* index register, a scaling factor, and a displacement.
|
|
|
|
* R - The mod field of the ModR/M byte may refer only to a general register.
|
|
|
|
* S - The reg field of the ModR/M byte selects a segment register.
|
|
|
|
* T - The reg field of the ModR/M byte selects a test register.
|
2007-04-19 20:12:21 +04:00
|
|
|
* U - The R/M field of the ModR/M byte selects a 128-bit XMM register.
|
2003-12-24 23:32:59 +03:00
|
|
|
* V - The reg field of the ModR/M byte selects a 128-bit XMM register.
|
2008-02-06 01:33:35 +03:00
|
|
|
* W - A ModR/M byte follows the opcode and specifies the operand. The
|
|
|
|
* operand is either a 128-bit XMM register or a memory address. If
|
|
|
|
* it is a memory address, the address is computed from a segment
|
2003-12-24 23:32:59 +03:00
|
|
|
* register and any of the following values: a base register, an
|
|
|
|
* index register, a scaling factor, and a displacement.
|
2004-10-18 02:05:17 +04:00
|
|
|
* X - Memory addressed by the DS:rSI register pair.
|
2004-12-09 23:01:00 +03:00
|
|
|
* Y - Memory addressed by the ES:rDI register pair.
|
2008-02-06 01:33:35 +03:00
|
|
|
*/
|
2003-12-24 23:32:59 +03:00
|
|
|
|
2008-02-06 01:33:35 +03:00
|
|
|
/*
|
2003-12-24 23:32:59 +03:00
|
|
|
* Codes for Operand Type:
|
|
|
|
* ----------------------
|
2008-02-06 01:33:35 +03:00
|
|
|
* a - Two one-word operands in memory or two double-word operands in
|
2003-12-24 23:32:59 +03:00
|
|
|
* memory, depending on operand-size attribute (used only by the BOUND
|
|
|
|
* instruction).
|
|
|
|
* b - Byte, regardless of operand-size attribute.
|
|
|
|
* d - Doubleword, regardless of operand-size attribute.
|
|
|
|
* dq - Double-quadword, regardless of operand-size attribute.
|
|
|
|
* p - 32-bit or 48-bit pointer, depending on operand-size attribute.
|
2004-10-18 02:05:17 +04:00
|
|
|
* pd - 128-bit packed double-precision floating-point data.
|
2004-12-09 23:01:00 +03:00
|
|
|
* pi - Quadword MMX technology register (packed integer)
|
2003-12-24 23:32:59 +03:00
|
|
|
* ps - 128-bit packed single-precision floating-point data.
|
|
|
|
* q - Quadword, regardless of operand-size attribute.
|
2004-10-18 02:05:17 +04:00
|
|
|
* s - 6-byte or 10-byte pseudo-descriptor.
|
2004-12-09 23:01:00 +03:00
|
|
|
* si - Doubleword integer register (scalar integer)
|
2003-12-24 23:32:59 +03:00
|
|
|
* ss - Scalar element of a 128-bit packed single-precision floating data.
|
2004-10-18 02:05:17 +04:00
|
|
|
* sd - Scalar element of a 128-bit packed double-precision floating data.
|
|
|
|
* v - Word, doubleword or quadword, depending on operand-size attribute.
|
2005-12-23 17:15:13 +03:00
|
|
|
* w - Word, regardless of operand-size attr.
|
2010-03-07 11:08:40 +03:00
|
|
|
* y - Doubleword or quadword (in 64-bit mode) depending on 32/64 bit
|
|
|
|
* operand size.
|
2003-12-24 23:32:59 +03:00
|
|
|
*/
|
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
// far call/jmp
|
|
|
|
void Apw(const x86_insn *insn);
|
|
|
|
void Apd(const x86_insn *insn);
|
|
|
|
|
|
|
|
// 8-bit general purpose registers
|
2009-01-19 22:01:03 +03:00
|
|
|
void AL_Reg(const x86_insn *insn);
|
|
|
|
void CL_Reg(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// 16-bit general purpose registers
|
2009-01-19 22:01:03 +03:00
|
|
|
void AX_Reg(const x86_insn *insn);
|
|
|
|
void DX_Reg(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// 32-bit general purpose registers
|
2009-01-19 22:01:03 +03:00
|
|
|
void EAX_Reg(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// 64-bit general purpose registers
|
2009-01-19 22:01:03 +03:00
|
|
|
void RAX_Reg(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// segment registers
|
|
|
|
void CS(const x86_insn *insn);
|
|
|
|
void DS(const x86_insn *insn);
|
|
|
|
void ES(const x86_insn *insn);
|
|
|
|
void SS(const x86_insn *insn);
|
|
|
|
void FS(const x86_insn *insn);
|
|
|
|
void GS(const x86_insn *insn);
|
|
|
|
|
|
|
|
// segment registers
|
|
|
|
void Sw(const x86_insn *insn);
|
|
|
|
|
|
|
|
// test registers
|
|
|
|
void Td(const x86_insn *insn);
|
|
|
|
|
|
|
|
// control register
|
|
|
|
void Cd(const x86_insn *insn);
|
|
|
|
void Cq(const x86_insn *insn);
|
|
|
|
|
|
|
|
// debug register
|
|
|
|
void Dd(const x86_insn *insn);
|
|
|
|
void Dq(const x86_insn *insn);
|
|
|
|
|
|
|
|
// 8-bit general purpose register
|
2009-01-19 22:01:03 +03:00
|
|
|
void Reg8(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// 16-bit general purpose register
|
|
|
|
void RX(const x86_insn *insn);
|
|
|
|
|
|
|
|
// 32-bit general purpose register
|
|
|
|
void ERX(const x86_insn *insn);
|
|
|
|
|
|
|
|
// 64-bit general purpose register
|
|
|
|
void RRX(const x86_insn *insn);
|
|
|
|
|
|
|
|
// general purpose register or memory operand
|
|
|
|
void Eb(const x86_insn *insn);
|
|
|
|
void Ew(const x86_insn *insn);
|
|
|
|
void Ed(const x86_insn *insn);
|
|
|
|
void Eq(const x86_insn *insn);
|
2010-03-07 11:08:40 +03:00
|
|
|
void Ey(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// general purpose register
|
|
|
|
void Gb(const x86_insn *insn);
|
|
|
|
void Gw(const x86_insn *insn);
|
|
|
|
void Gd(const x86_insn *insn);
|
|
|
|
void Gq(const x86_insn *insn);
|
2010-03-26 13:39:40 +03:00
|
|
|
void Gy(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
2007-04-19 20:12:21 +04:00
|
|
|
void Hbd(const x86_insn *insn);
|
|
|
|
void Hwd(const x86_insn *insn);
|
|
|
|
void Hd(const x86_insn *insn);
|
|
|
|
void Hq(const x86_insn *insn);
|
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
// immediate
|
|
|
|
void I1(const x86_insn *insn);
|
|
|
|
void Ib(const x86_insn *insn);
|
|
|
|
void Iw(const x86_insn *insn);
|
|
|
|
void Id(const x86_insn *insn);
|
|
|
|
void Iq(const x86_insn *insn);
|
|
|
|
|
2007-09-19 23:38:10 +04:00
|
|
|
// double immediate
|
|
|
|
void IbIb(const x86_insn *insn);
|
2006-03-23 20:43:39 +03:00
|
|
|
void IwIb(const x86_insn *insn);
|
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
// sign extended immediate
|
|
|
|
void sIbw(const x86_insn *insn);
|
|
|
|
void sIbd(const x86_insn *insn);
|
|
|
|
void sIbq(const x86_insn *insn);
|
|
|
|
void sIdq(const x86_insn *insn);
|
|
|
|
|
|
|
|
// floating point
|
|
|
|
void ST0(const x86_insn *insn);
|
|
|
|
void STi(const x86_insn *insn);
|
|
|
|
|
|
|
|
// general purpose register
|
|
|
|
void Rw(const x86_insn *insn);
|
|
|
|
void Rd(const x86_insn *insn);
|
|
|
|
void Rq(const x86_insn *insn);
|
|
|
|
|
|
|
|
// mmx register
|
|
|
|
void Pq(const x86_insn *insn);
|
|
|
|
|
|
|
|
// mmx register or memory operand
|
|
|
|
void Qd(const x86_insn *insn);
|
|
|
|
void Qq(const x86_insn *insn);
|
|
|
|
void Vq(const x86_insn *insn);
|
2006-02-17 16:33:05 +03:00
|
|
|
void Nq(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// xmm register
|
2010-03-19 17:43:13 +03:00
|
|
|
void Ups(const x86_insn *insn);
|
|
|
|
void Upd(const x86_insn *insn);
|
2006-02-17 16:33:05 +03:00
|
|
|
void Udq(const x86_insn *insn);
|
2010-03-19 17:43:13 +03:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
void Vdq(const x86_insn *insn);
|
|
|
|
void Vss(const x86_insn *insn);
|
|
|
|
void Vsd(const x86_insn *insn);
|
|
|
|
void Vps(const x86_insn *insn);
|
|
|
|
void Vpd(const x86_insn *insn);
|
|
|
|
|
|
|
|
// xmm register or memory operand
|
2007-04-19 20:12:21 +04:00
|
|
|
void Ww(const x86_insn *insn);
|
|
|
|
void Wd(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
void Wq(const x86_insn *insn);
|
2007-04-19 20:12:21 +04:00
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
void Wdq(const x86_insn *insn);
|
|
|
|
void Wss(const x86_insn *insn);
|
|
|
|
void Wsd(const x86_insn *insn);
|
|
|
|
void Wps(const x86_insn *insn);
|
|
|
|
void Wpd(const x86_insn *insn);
|
|
|
|
|
|
|
|
// direct memory access
|
|
|
|
void OP_O(const x86_insn *insn, unsigned size);
|
|
|
|
void Ob(const x86_insn *insn);
|
|
|
|
void Ow(const x86_insn *insn);
|
|
|
|
void Od(const x86_insn *insn);
|
|
|
|
void Oq(const x86_insn *insn);
|
|
|
|
|
|
|
|
// memory operand
|
|
|
|
void OP_M(const x86_insn *insn, unsigned size);
|
|
|
|
void Ma(const x86_insn *insn);
|
|
|
|
void Mp(const x86_insn *insn);
|
|
|
|
void Ms(const x86_insn *insn);
|
|
|
|
void Mx(const x86_insn *insn);
|
|
|
|
void Mb(const x86_insn *insn);
|
|
|
|
void Mw(const x86_insn *insn);
|
|
|
|
void Md(const x86_insn *insn);
|
|
|
|
void Mq(const x86_insn *insn);
|
|
|
|
void Mt(const x86_insn *insn);
|
|
|
|
void Mdq(const x86_insn *insn);
|
|
|
|
void Mps(const x86_insn *insn);
|
|
|
|
void Mpd(const x86_insn *insn);
|
2007-08-31 22:09:34 +04:00
|
|
|
void Mss(const x86_insn *insn);
|
|
|
|
void Msd(const x86_insn *insn);
|
2005-12-23 17:15:13 +03:00
|
|
|
|
|
|
|
// string instructions
|
|
|
|
void OP_X(const x86_insn *insn, unsigned size);
|
|
|
|
void Xb(const x86_insn *insn);
|
|
|
|
void Xw(const x86_insn *insn);
|
|
|
|
void Xd(const x86_insn *insn);
|
|
|
|
void Xq(const x86_insn *insn);
|
|
|
|
|
|
|
|
// string instructions
|
|
|
|
void OP_Y(const x86_insn *insn, unsigned size);
|
|
|
|
void Yb(const x86_insn *insn);
|
|
|
|
void Yw(const x86_insn *insn);
|
|
|
|
void Yd(const x86_insn *insn);
|
|
|
|
void Yq(const x86_insn *insn);
|
|
|
|
|
2009-08-21 17:45:38 +04:00
|
|
|
// maskmovdq/maskmovdqu
|
|
|
|
void OP_sY(const x86_insn *insn, unsigned size);
|
|
|
|
void sYq(const x86_insn *insn);
|
|
|
|
void sYdq(const x86_insn *insn);
|
|
|
|
|
2005-12-23 17:15:13 +03:00
|
|
|
// jump offset
|
|
|
|
void Jb(const x86_insn *insn);
|
|
|
|
void Jw(const x86_insn *insn);
|
|
|
|
void Jd(const x86_insn *insn);
|
2003-12-24 23:32:59 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|