Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
1774db38
Commit
1774db38
authored
Feb 27, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winedbg: Use the Zydis library for disassembly.
parent
7bc94bc8
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
92 additions
and
3505 deletions
+92
-3505
Makefile.in
programs/winedbg/Makefile.in
+2
-3
be_i386.c
programs/winedbg/be_i386.c
+1
-4
be_x86_64.c
programs/winedbg/be_x86_64.c
+1
-3
db_disasm.c
programs/winedbg/db_disasm.c
+0
-1815
db_disasm64.c
programs/winedbg/db_disasm64.c
+0
-1670
debugger.h
programs/winedbg/debugger.h
+1
-0
memory.c
programs/winedbg/memory.c
+87
-10
No files found.
programs/winedbg/Makefile.in
View file @
1774db38
MODULE
=
winedbg.exe
IMPORTS
=
dbghelp advapi32
IMPORTS
=
$(ZYDIS_PE_LIBS)
dbghelp advapi32
EXTRAINCL
=
$(ZYDIS_PE_CFLAGS)
DELAYIMPORTS
=
comdlg32 shell32 comctl32 user32 gdi32 ws2_32
EXTRADLLFLAGS
=
-mconsole
...
...
@@ -11,8 +12,6 @@ C_SRCS = \
be_x86_64.c
\
break.c
\
crashdlg.c
\
db_disasm.c
\
db_disasm64.c
\
display.c
\
expr.c
\
gdbproxy.c
\
...
...
programs/winedbg/be_i386.c
View file @
1774db38
...
...
@@ -25,9 +25,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
winedbg
);
/* db_disasm.c */
extern
void
be_i386_disasm_one_insn
(
ADDRESS64
*
addr
,
int
display
);
#define STEP_FLAG 0x00000100
/* single step flag */
#define V86_FLAG 0x00020000
...
...
@@ -852,7 +849,7 @@ struct backend_cpu be_i386 =
be_i386_is_break_insn
,
be_i386_is_func_call
,
be_i386_is_jump
,
be_i386_disasm_one
_insn
,
memory_disasm_one_x86
_insn
,
be_i386_insert_Xpoint
,
be_i386_remove_Xpoint
,
be_i386_is_watchpoint_set
,
...
...
programs/winedbg/be_x86_64.c
View file @
1774db38
...
...
@@ -539,8 +539,6 @@ static BOOL be_x86_64_is_jump(const void* insn, ADDRESS64* jumpee)
return
FALSE
;
}
extern
void
be_x86_64_disasm_one_insn
(
ADDRESS64
*
addr
,
int
display
);
#define DR7_CONTROL_SHIFT 16
#define DR7_CONTROL_SIZE 4
...
...
@@ -790,7 +788,7 @@ struct backend_cpu be_x86_64 =
be_x86_64_is_break_insn
,
be_x86_64_is_func_call
,
be_x86_64_is_jump
,
be_x86_64_disasm_one
_insn
,
memory_disasm_one_x86
_insn
,
be_x86_64_insert_Xpoint
,
be_x86_64_remove_Xpoint
,
be_x86_64_is_watchpoint_set
,
...
...
programs/winedbg/db_disasm.c
deleted
100644 → 0
View file @
7bc94bc8
/*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* HISTORY
*
* Revision 2.6 92/01/03 20:05:00 dbg
* Add a switch to disassemble 16-bit code.
* Fix spelling of 'lods' opcodes.
* [91/10/30 dbg]
*
* Revision 2.5 91/10/09 16:05:58 af
* Supported disassemble of non current task by passing task parameter.
* [91/08/29 tak]
*
* Revision 2.4 91/05/14 16:05:04 mrt
* Correcting copyright
*
* Revision 2.3 91/02/05 17:11:03 mrt
* Changed to new Mach copyright
* [91/02/01 17:31:03 mrt]
*
* Revision 2.2 90/08/27 21:55:56 dbg
* Fix register operand for move to/from control/test/debug
* register instructions. Add i486 instructions.
* [90/08/27 dbg]
*
* Import db_sym.h. Print instruction displacements in
* current radix (signed). Change calling sequence of
* db_disasm.
* [90/08/21 dbg]
* Fix includes.
* [90/08/08 dbg]
* Created.
* [90/07/25 dbg]
*
*/
/*
* Instruction disassembler.
*/
#include "debugger.h"
#if defined(__i386__) || defined(__x86_64__)
/*
* Switch to disassemble 16-bit code.
*/
static
BOOL
db_disasm_16
=
FALSE
;
/*
* Flag to indicate whether we need to display instruction,
* or whether we just need to know the address of the next
* instruction.
*/
static
BOOL
db_display
=
FALSE
;
/*
* Size attributes
*/
#define BYTE 0
#define WORD 1
#define LONG 2
#define QUAD 3
#define DQUA 4
#define SNGL 5
#define DBLR 6
#define EXTR 7
#define SDEP 8
#define NONE 9
/*
* Addressing modes
*/
#define E 1
/* general effective address */
#define Eind 2
/* indirect address (jump, call) */
#define Ew 3
/* address, word size */
#define Eb 4
/* address, byte size */
#define R 5
/* register, in 'reg' field */
#define Rw 6
/* word register, in 'reg' field */
#define Ri 7
/* register in instruction */
#define S 8
/* segment reg, in 'reg' field */
#define Si 9
/* segment reg, in instruction */
#define A 10
/* accumulator */
#define BX 11
/* (bx) */
#define CL 12
/* cl, for shifts */
#define DX 13
/* dx, for IO */
#define SI 14
/* si */
#define DI 15
/* di */
#define CR 16
/* control register */
#define DR 17
/* debug register */
#define TR 18
/* test register */
#define I 19
/* immediate, unsigned */
#define Is 20
/* immediate, signed */
#define Ib 21
/* byte immediate, unsigned */
#define Ibs 22
/* byte immediate, signed */
#define Iw 23
/* word immediate, unsigned */
#define Il 24
/* long immediate */
#define O 25
/* direct address */
#define Db 26
/* byte displacement from EIP */
#define Dl 27
/* long displacement from EIP */
#define o1 28
/* constant 1 */
#define o3 29
/* constant 3 */
#define OS 30
/* immediate offset/segment */
#define ST 31
/* FP stack top */
#define STI 32
/* FP stack */
#define X 33
/* extended FP op */
#define XA 34
/* for 'fstcw %ax' */
#define MX 35
/* special register (MMX reg %mm0-7) */
#define EMX 36
/* special register (MMX reg %mm0-7) */
#define XMM 37
/* special register (floating point reg %xmm0-7) */
#define EXMM 38
/* special register (floating point reg %xmm0-7) */
struct
inst
{
const
char
*
i_name
;
/* name */
short
i_has_modrm
;
/* has regmodrm byte */
short
i_size
;
/* operand size */
int
i_mode
;
/* addressing modes */
const
char
*
i_extra
;
/* pointer to extra opcode table */
};
#define op1(x) (x)
#define op2(x,y) ((x)|((y)<<8))
#define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
struct
finst
{
const
char
*
f_name
;
/* name for memory instruction */
int
f_size
;
/* size for memory instruction */
int
f_rrmode
;
/* mode for rr instruction */
const
char
*
f_rrname
;
/* name for rr instruction
(or pointer to table) */
};
static
const
char
*
const
db_Grp6
[]
=
{
"sldt"
,
"str"
,
"lldt"
,
"ltr"
,
"verr"
,
"verw"
,
""
,
""
};
static
const
char
*
const
db_Grp7
[]
=
{
"sgdt"
,
"sidt"
,
"lgdt"
,
"lidt"
,
"smsw"
,
""
,
"lmsw"
,
"invlpg"
};
static
const
char
*
const
db_Grp8
[]
=
{
""
,
""
,
""
,
""
,
"bt"
,
"bts"
,
"btr"
,
"btc"
};
static
const
char
*
const
db_Grp10
[]
=
{
"(bad)"
,
"(bad)"
,
"psrlw"
,
"(bad)"
,
"psraw"
,
"(bad)"
,
"psllw"
,
"(bad)"
};
static
const
char
*
const
db_Grp11
[]
=
{
"(bad)"
,
"(bad)"
,
"psrld"
,
"(bad)"
,
"psrad"
,
"(bad)"
,
"pslld"
,
"(bad)"
};
static
const
char
*
const
db_Grp12
[]
=
{
"(bad)"
,
"(bad)"
,
"psrlq"
,
"(bad)"
,
"psraq"
,
"(bad)"
,
"psllq"
,
"(bad)"
};
static
const
struct
inst
db_inst_0f0x
[]
=
{
/*00*/
{
""
,
TRUE
,
NONE
,
op1
(
Ew
),
(
const
char
*
)
db_Grp6
},
/*01*/
{
""
,
TRUE
,
NONE
,
op1
(
Ew
),
(
const
char
*
)
db_Grp7
},
/*02*/
{
"lar"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*03*/
{
"lsl"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*04*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*05*/
{
"syscall"
,
FALSE
,
NONE
,
0
,
0
},
/*06*/
{
"clts"
,
FALSE
,
NONE
,
0
,
0
},
/*07*/
{
"sysret"
,
FALSE
,
NONE
,
0
,
0
},
/*08*/
{
"invd"
,
FALSE
,
NONE
,
0
,
0
},
/*09*/
{
"wbinvd"
,
FALSE
,
NONE
,
0
,
0
},
/*0a*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0b*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0c*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0d*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
db_inst_0f2x
[]
=
{
/*20*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
CR
,
E
),
0
},
/* use E for reg */
/*21*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
DR
,
E
),
0
},
/* since mod == 11 */
/*22*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
E
,
CR
),
0
},
/*23*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
E
,
DR
),
0
},
/*24*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
TR
,
E
),
0
},
/*25*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*26*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
E
,
TR
),
0
},
/*27*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*28*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*29*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2a*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2b*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2c*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2d*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
db_inst_0f3x
[]
=
{
/*30*/
{
"wrmsr"
,
FALSE
,
NONE
,
0
,
0
},
/*31*/
{
"rdtsc"
,
FALSE
,
NONE
,
0
,
0
},
/*32*/
{
"rdmsr"
,
FALSE
,
NONE
,
0
,
0
},
/*33*/
{
"rdpmc"
,
FALSE
,
NONE
,
0
,
0
},
/*34*/
{
"sysenter"
,
FALSE
,
NONE
,
0
,
0
},
/*35*/
{
"sysexit"
,
FALSE
,
NONE
,
0
,
0
},
/*36*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*37*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*38*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*39*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*3a*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*3b*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*3c*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*3d*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*3e*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*3f*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
db_inst_0f4x
[]
=
{
/*40*/
{
"cmovo"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*41*/
{
"cmovno"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*42*/
{
"cmovnae"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*43*/
{
"cmovnb"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*44*/
{
"cmove"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*45*/
{
"cmovne"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*46*/
{
"cmovna"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*47*/
{
"cmova"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*48*/
{
"cmovs"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*49*/
{
"cmovns"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4a*/
{
"cmovpe"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4b*/
{
"cmovpo"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4c*/
{
"cmovl"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4d*/
{
"cmovge"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4e*/
{
"cmovle"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4f*/
{
"cmovnle"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
};
static
const
struct
inst
db_inst_0f5x
[]
=
{
/*50*/
{
"movmskps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
R
),
0
},
/*51*/
{
"sqrtps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*52*/
{
"rsqrtps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*53*/
{
"rcpps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*54*/
{
"andps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*55*/
{
"andnps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*56*/
{
"orps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*57*/
{
"xorps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*58*/
{
"addps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*59*/
{
"mulps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5a*/
{
"cvtps2pd"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5b*/
{
"cvtdq2ps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5c*/
{
"subps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5d*/
{
"minps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5e*/
{
"divps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5f*/
{
"maxps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
};
static
const
struct
inst
db_inst_0f6x
[]
=
{
/*60*/
{
"punpcklbw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*61*/
{
"punpcklwd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*62*/
{
"punpckldq"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*63*/
{
"packsswb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*64*/
{
"pcmpgtb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*65*/
{
"pcmpgtw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*66*/
{
"pcmpgtd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*67*/
{
"packuswb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*68*/
{
"punpckhbw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*69*/
{
"punpckhwd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6a*/
{
"punpckhdq"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6b*/
{
"packssdw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6c*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*6d*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*6e*/
{
"movd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6f*/
{
"movq"
,
TRUE
,
NONE
,
op2
(
EMX
,
MX
),
0
},
};
static
const
struct
inst
db_inst_0f7x
[]
=
{
/*70*/
{
"pshufw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*71*/
{
"(grp10)"
,
TRUE
,
BYTE
,
op2
(
EMX
,
I
),
(
const
char
*
)
db_Grp10
},
/*72*/
{
"(grp11)"
,
TRUE
,
BYTE
,
op2
(
EMX
,
I
),
(
const
char
*
)
db_Grp11
},
/*73*/
{
"(grp12)"
,
TRUE
,
BYTE
,
op2
(
EMX
,
I
),
(
const
char
*
)
db_Grp12
},
/*74*/
{
"pcmpeqb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*75*/
{
"pcmpeqw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*76*/
{
"pcmpeqd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*77*/
{
"emms"
,
FALSE
,
NONE
,
0
,
0
},
/*78*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*79*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7a*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7b*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7c*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7d*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7e*/
{
"movd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*7f*/
{
"movq"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
};
static
const
struct
inst
db_inst_0f8x
[]
=
{
/*80*/
{
"jo"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*81*/
{
"jno"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*82*/
{
"jb"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*83*/
{
"jnb"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*84*/
{
"jz"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*85*/
{
"jnz"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*86*/
{
"jbe"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*87*/
{
"jnbe"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*88*/
{
"js"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*89*/
{
"jns"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8a*/
{
"jp"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8b*/
{
"jnp"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8c*/
{
"jl"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8d*/
{
"jnl"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8e*/
{
"jle"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8f*/
{
"jnle"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
};
static
const
struct
inst
db_inst_0f9x
[]
=
{
/*90*/
{
"seto"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*91*/
{
"setno"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*92*/
{
"setb"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*93*/
{
"setnb"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*94*/
{
"setz"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*95*/
{
"setnz"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*96*/
{
"setbe"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*97*/
{
"setnbe"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*98*/
{
"sets"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*99*/
{
"setns"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9a*/
{
"setp"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9b*/
{
"setnp"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9c*/
{
"setl"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9d*/
{
"setnl"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9e*/
{
"setle"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9f*/
{
"setnle"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
};
static
const
struct
inst
db_inst_0fax
[]
=
{
/*a0*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*a1*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*a2*/
{
"cpuid"
,
FALSE
,
NONE
,
0
,
0
},
/*a3*/
{
"bt"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*a4*/
{
"shld"
,
TRUE
,
LONG
,
op3
(
Ib
,
E
,
R
),
0
},
/*a5*/
{
"shld"
,
TRUE
,
LONG
,
op3
(
CL
,
E
,
R
),
0
},
/*a6*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*a7*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*a8*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*a9*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*aa*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*ab*/
{
"bts"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*ac*/
{
"shrd"
,
TRUE
,
LONG
,
op3
(
Ib
,
E
,
R
),
0
},
/*ad*/
{
"shrd"
,
TRUE
,
LONG
,
op3
(
CL
,
E
,
R
),
0
},
/*a6*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*a7*/
{
"imul"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
};
static
const
struct
inst
db_inst_0fbx
[]
=
{
/*b0*/
{
"cmpxchg"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*b1*/
{
"cmpxchg"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b2*/
{
"lss"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b3*/
{
"bts"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*b4*/
{
"lfs"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b5*/
{
"lgs"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b6*/
{
"movzb"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b7*/
{
"movzw"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b8*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*b9*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*ba*/
{
""
,
TRUE
,
LONG
,
op2
(
Ib
,
E
),
(
const
char
*
)
db_Grp8
},
/*bb*/
{
"btc"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*bc*/
{
"bsf"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*bd*/
{
"bsr"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*be*/
{
"movsb"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*bf*/
{
"movsw"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
};
static
const
struct
inst
db_inst_0fcx
[]
=
{
/*c0*/
{
"xadd"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*c1*/
{
"xadd"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*c2*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c3*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c4*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c5*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c6*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c7*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c8*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*c9*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*ca*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*cb*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*cc*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*cd*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*ce*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*cf*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
};
static
const
struct
inst
db_inst_0fdx
[]
=
{
/*d0*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*d1*/
{
"psrlw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*d2*/
{
"psrld"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*d3*/
{
"psrld"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*d4*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*d5*/
{
"pmulww"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*d6*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*d7*/
{
"pmovmskb"
,
FALSE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*d8*/
{
"psubusb"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*d9*/
{
"psubusw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*da*/
{
"pminub"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*db*/
{
"pand"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*dc*/
{
"paddusb"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*dd*/
{
"paddusw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*de*/
{
"pmaxub"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*df*/
{
"pandn"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
};
static
const
struct
inst
db_inst_0fex
[]
=
{
/*e0*/
{
"pavgb"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e1*/
{
"psraw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e2*/
{
"psrad"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e3*/
{
"pavgw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e4*/
{
"pmulhuw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e5*/
{
"pmulhw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e6*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*e7*/
{
"movntq"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e8*/
{
"psubsb"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*e9*/
{
"psubsw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*ea*/
{
"pminsw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*eb*/
{
"por"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*ec*/
{
"paddsb"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*ed*/
{
"paddsw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*ee*/
{
"pmaxsw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*ef*/
{
"pxor"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
};
static
const
struct
inst
db_inst_0ffx
[]
=
{
/*f0*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*f1*/
{
"psllw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*f2*/
{
"pslld"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*f3*/
{
"psllq"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*f4*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*f5*/
{
"pmaddwd"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*f6*/
{
"psadbw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*f7*/
{
"maskmovq"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*f8*/
{
"psubb"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*f9*/
{
"psubw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*fa*/
{
"psubd"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*fb*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
/*fc*/
{
"paddb"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*fd*/
{
"paddw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*fe*/
{
"paddd"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*ff*/
{
"(bad)"
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
*
const
db_inst_0f
[]
=
{
db_inst_0f0x
,
0
,
db_inst_0f2x
,
db_inst_0f3x
,
db_inst_0f4x
,
db_inst_0f5x
,
db_inst_0f6x
,
db_inst_0f7x
,
db_inst_0f8x
,
db_inst_0f9x
,
db_inst_0fax
,
db_inst_0fbx
,
db_inst_0fcx
,
db_inst_0fdx
,
db_inst_0fex
,
db_inst_0ffx
};
static
const
char
*
const
db_Esc92
[]
=
{
"fnop"
,
""
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Esc93
[]
=
{
""
,
""
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Esc94
[]
=
{
"fchs"
,
"fabs"
,
""
,
""
,
"ftst"
,
"fxam"
,
""
,
""
};
static
const
char
*
const
db_Esc95
[]
=
{
"fld1"
,
"fldl2t"
,
"fldl2e"
,
"fldpi"
,
"fldlg2"
,
"fldln2"
,
"fldz"
,
""
};
static
const
char
*
const
db_Esc96
[]
=
{
"f2xm1"
,
"fyl2x"
,
"fptan"
,
"fpatan"
,
"fxtract"
,
"fprem1"
,
"fdecstp"
,
"fincstp"
};
static
const
char
*
const
db_Esc97
[]
=
{
"fprem"
,
"fyl2xp1"
,
"fsqrt"
,
"fsincos"
,
"frndint"
,
"fscale"
,
"fsin"
,
"fcos"
};
static
const
char
*
const
db_Esca4
[]
=
{
""
,
"fucompp"
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Escb4
[]
=
{
""
,
""
,
"fnclex"
,
"fninit"
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Esce3
[]
=
{
""
,
"fcompp"
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Escf4
[]
=
{
"fnstsw"
,
""
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
struct
finst
db_Esc8
[]
=
{
/*0*/
{
"fadd"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*1*/
{
"fmul"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*2*/
{
"fcom"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*3*/
{
"fcomp"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*4*/
{
"fsub"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*5*/
{
"fsubr"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*6*/
{
"fdiv"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*7*/
{
"fdivr"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
};
static
const
struct
finst
db_Esc9
[]
=
{
/*0*/
{
"fld"
,
SNGL
,
op1
(
STI
),
0
},
/*1*/
{
""
,
NONE
,
op1
(
STI
),
"fxch"
},
/*2*/
{
"fst"
,
SNGL
,
op1
(
X
),
(
const
char
*
)
db_Esc92
},
/*3*/
{
"fstp"
,
SNGL
,
op1
(
X
),
(
const
char
*
)
db_Esc93
},
/*4*/
{
"fldenv"
,
NONE
,
op1
(
X
),
(
const
char
*
)
db_Esc94
},
/*5*/
{
"fldcw"
,
NONE
,
op1
(
X
),
(
const
char
*
)
db_Esc95
},
/*6*/
{
"fnstenv"
,
NONE
,
op1
(
X
),
(
const
char
*
)
db_Esc96
},
/*7*/
{
"fnstcw"
,
NONE
,
op1
(
X
),
(
const
char
*
)
db_Esc97
},
};
static
const
struct
finst
db_Esca
[]
=
{
/*0*/
{
"fiadd"
,
WORD
,
0
,
0
},
/*1*/
{
"fimul"
,
WORD
,
0
,
0
},
/*2*/
{
"ficom"
,
WORD
,
0
,
0
},
/*3*/
{
"ficomp"
,
WORD
,
0
,
0
},
/*4*/
{
"fisub"
,
WORD
,
op1
(
X
),
(
const
char
*
)
db_Esca4
},
/*5*/
{
"fisubr"
,
WORD
,
0
,
0
},
/*6*/
{
"fidiv"
,
WORD
,
0
,
0
},
/*7*/
{
"fidivr"
,
WORD
,
0
,
0
}
};
static
const
struct
finst
db_Escb
[]
=
{
/*0*/
{
"fild"
,
WORD
,
0
,
0
},
/*1*/
{
""
,
NONE
,
0
,
0
},
/*2*/
{
"fist"
,
WORD
,
0
,
0
},
/*3*/
{
"fistp"
,
WORD
,
0
,
0
},
/*4*/
{
""
,
WORD
,
op1
(
X
),
(
const
char
*
)
db_Escb4
},
/*5*/
{
"fld"
,
EXTR
,
0
,
0
},
/*6*/
{
""
,
WORD
,
0
,
0
},
/*7*/
{
"fstp"
,
EXTR
,
0
,
0
},
};
static
const
struct
finst
db_Escc
[]
=
{
/*0*/
{
"fadd"
,
DBLR
,
op2
(
ST
,
STI
),
0
},
/*1*/
{
"fmul"
,
DBLR
,
op2
(
ST
,
STI
),
0
},
/*2*/
{
"fcom"
,
DBLR
,
op2
(
ST
,
STI
),
0
},
/*3*/
{
"fcomp"
,
DBLR
,
op2
(
ST
,
STI
),
0
},
/*4*/
{
"fsub"
,
DBLR
,
op2
(
ST
,
STI
),
"fsubr"
},
/*5*/
{
"fsubr"
,
DBLR
,
op2
(
ST
,
STI
),
"fsub"
},
/*6*/
{
"fdiv"
,
DBLR
,
op2
(
ST
,
STI
),
"fdivr"
},
/*7*/
{
"fdivr"
,
DBLR
,
op2
(
ST
,
STI
),
"fdiv"
},
};
static
const
struct
finst
db_Escd
[]
=
{
/*0*/
{
"fld"
,
DBLR
,
op1
(
STI
),
"ffree"
},
/*1*/
{
""
,
NONE
,
0
,
0
},
/*2*/
{
"fst"
,
DBLR
,
op1
(
STI
),
0
},
/*3*/
{
"fstp"
,
DBLR
,
op1
(
STI
),
0
},
/*4*/
{
"frstor"
,
NONE
,
op1
(
STI
),
"fucom"
},
/*5*/
{
""
,
NONE
,
op1
(
STI
),
"fucomp"
},
/*6*/
{
"fnsave"
,
NONE
,
0
,
0
},
/*7*/
{
"fnstsw"
,
NONE
,
0
,
0
},
};
static
const
struct
finst
db_Esce
[]
=
{
/*0*/
{
"fiadd"
,
LONG
,
op2
(
ST
,
STI
),
"faddp"
},
/*1*/
{
"fimul"
,
LONG
,
op2
(
ST
,
STI
),
"fmulp"
},
/*2*/
{
"ficom"
,
LONG
,
0
,
0
},
/*3*/
{
"ficomp"
,
LONG
,
op1
(
X
),
(
const
char
*
)
db_Esce3
},
/*4*/
{
"fisub"
,
LONG
,
op2
(
ST
,
STI
),
"fsubrp"
},
/*5*/
{
"fisubr"
,
LONG
,
op2
(
ST
,
STI
),
"fsubp"
},
/*6*/
{
"fidiv"
,
LONG
,
op2
(
ST
,
STI
),
"fdivrp"
},
/*7*/
{
"fidivr"
,
LONG
,
op2
(
ST
,
STI
),
"fdivp"
},
};
static
const
struct
finst
db_Escf
[]
=
{
/*0*/
{
"fild"
,
LONG
,
0
,
0
},
/*1*/
{
""
,
LONG
,
0
,
0
},
/*2*/
{
"fist"
,
LONG
,
0
,
0
},
/*3*/
{
"fistp"
,
LONG
,
0
,
0
},
/*4*/
{
"fbld"
,
NONE
,
op1
(
XA
),
(
const
char
*
)
db_Escf4
},
/*5*/
{
"fld"
,
QUAD
,
0
,
0
},
/*6*/
{
"fbstp"
,
NONE
,
0
,
0
},
/*7*/
{
"fstp"
,
QUAD
,
0
,
0
},
};
static
const
struct
finst
*
const
db_Esc_inst
[]
=
{
db_Esc8
,
db_Esc9
,
db_Esca
,
db_Escb
,
db_Escc
,
db_Escd
,
db_Esce
,
db_Escf
};
static
const
char
*
const
db_Grp1
[]
=
{
"add"
,
"or"
,
"adc"
,
"sbb"
,
"and"
,
"sub"
,
"xor"
,
"cmp"
};
static
const
char
*
const
db_Grp2
[]
=
{
"rol"
,
"ror"
,
"rcl"
,
"rcr"
,
"shl"
,
"shr"
,
"shl"
,
"sar"
};
static
const
struct
inst
db_Grp3
[]
=
{
{
"test"
,
TRUE
,
NONE
,
op2
(
I
,
E
),
0
},
{
"test"
,
TRUE
,
NONE
,
op2
(
I
,
E
),
0
},
{
"not"
,
TRUE
,
NONE
,
op1
(
E
),
0
},
{
"neg"
,
TRUE
,
NONE
,
op1
(
E
),
0
},
{
"mul"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
{
"imul"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
{
"div"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
{
"idiv"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
};
static
const
struct
inst
db_Grp4
[]
=
{
{
"inc"
,
TRUE
,
BYTE
,
op1
(
E
),
0
},
{
"dec"
,
TRUE
,
BYTE
,
op1
(
E
),
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
}
};
static
const
struct
inst
db_Grp5
[]
=
{
{
"inc"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
{
"dec"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
{
"call"
,
TRUE
,
NONE
,
op1
(
Eind
),
0
},
{
"lcall"
,
TRUE
,
NONE
,
op1
(
Eind
),
0
},
{
"jmp"
,
TRUE
,
NONE
,
op1
(
Eind
),
0
},
{
"ljmp"
,
TRUE
,
NONE
,
op1
(
Eind
),
0
},
{
"push"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
}
};
static
const
struct
inst
db_inst_table
[
256
]
=
{
/*00*/
{
"add"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*01*/
{
"add"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*02*/
{
"add"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*03*/
{
"add"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*04*/
{
"add"
,
FALSE
,
BYTE
,
op2
(
Is
,
A
),
0
},
/*05*/
{
"add"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*06*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*07*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*08*/
{
"or"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*09*/
{
"or"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*0a*/
{
"or"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*0b*/
{
"or"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*0c*/
{
"or"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*0d*/
{
"or"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*0e*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*0f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*10*/
{
"adc"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*11*/
{
"adc"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*12*/
{
"adc"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*13*/
{
"adc"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*14*/
{
"adc"
,
FALSE
,
BYTE
,
op2
(
Is
,
A
),
0
},
/*15*/
{
"adc"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*16*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*17*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*18*/
{
"sbb"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*19*/
{
"sbb"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*1a*/
{
"sbb"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*1b*/
{
"sbb"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*1c*/
{
"sbb"
,
FALSE
,
BYTE
,
op2
(
Is
,
A
),
0
},
/*1d*/
{
"sbb"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*1e*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*1f*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*20*/
{
"and"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*21*/
{
"and"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*22*/
{
"and"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*23*/
{
"and"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*24*/
{
"and"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*25*/
{
"and"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*26*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*27*/
{
"aaa"
,
FALSE
,
NONE
,
0
,
0
},
/*28*/
{
"sub"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*29*/
{
"sub"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*2a*/
{
"sub"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*2b*/
{
"sub"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*2c*/
{
"sub"
,
FALSE
,
BYTE
,
op2
(
Is
,
A
),
0
},
/*2d*/
{
"sub"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*2e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2f*/
{
"das"
,
FALSE
,
NONE
,
0
,
0
},
/*30*/
{
"xor"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*31*/
{
"xor"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*32*/
{
"xor"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*33*/
{
"xor"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*34*/
{
"xor"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*35*/
{
"xor"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*36*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*37*/
{
"daa"
,
FALSE
,
NONE
,
0
,
0
},
/*38*/
{
"cmp"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*39*/
{
"cmp"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*3a*/
{
"cmp"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*3b*/
{
"cmp"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*3c*/
{
"cmp"
,
FALSE
,
BYTE
,
op2
(
Is
,
A
),
0
},
/*3d*/
{
"cmp"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*3e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3f*/
{
"aas"
,
FALSE
,
NONE
,
0
,
0
},
/*40*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*41*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*42*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*43*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*44*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*45*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*46*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*47*/
{
"inc"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*48*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*49*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*4a*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*4b*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*4c*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*4d*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*4e*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*4f*/
{
"dec"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*50*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*51*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*52*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*53*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*54*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*55*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*56*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*57*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*58*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*59*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5a*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5b*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5c*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5d*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5e*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5f*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*60*/
{
"pusha"
,
FALSE
,
LONG
,
0
,
0
},
/*61*/
{
"popa"
,
FALSE
,
LONG
,
0
,
0
},
/*62*/
{
"bound"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*63*/
{
"arpl"
,
TRUE
,
NONE
,
op2
(
Ew
,
Rw
),
0
},
/*64*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*65*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*66*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*67*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*68*/
{
"push"
,
FALSE
,
LONG
,
op1
(
I
),
0
},
/*69*/
{
"imul"
,
TRUE
,
LONG
,
op3
(
I
,
E
,
R
),
0
},
/*6a*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ib
),
0
},
/*6b*/
{
"imul"
,
TRUE
,
LONG
,
op3
(
Ibs
,
E
,
R
),
0
},
/*6c*/
{
"ins"
,
FALSE
,
BYTE
,
op2
(
DX
,
DI
),
0
},
/*6d*/
{
"ins"
,
FALSE
,
LONG
,
op2
(
DX
,
DI
),
0
},
/*6e*/
{
"outs"
,
FALSE
,
BYTE
,
op2
(
SI
,
DX
),
0
},
/*6f*/
{
"outs"
,
FALSE
,
LONG
,
op2
(
SI
,
DX
),
0
},
/*70*/
{
"jo"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*71*/
{
"jno"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*72*/
{
"jb"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*73*/
{
"jnb"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*74*/
{
"jz"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*75*/
{
"jnz"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*76*/
{
"jbe"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*77*/
{
"jnbe"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*78*/
{
"js"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*79*/
{
"jns"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7a*/
{
"jp"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7b*/
{
"jnp"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7c*/
{
"jl"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7d*/
{
"jnl"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7e*/
{
"jle"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7f*/
{
"jnle"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*80*/
{
""
,
TRUE
,
BYTE
,
op2
(
I
,
E
),
(
const
char
*
)
db_Grp1
},
/*81*/
{
""
,
TRUE
,
LONG
,
op2
(
I
,
E
),
(
const
char
*
)
db_Grp1
},
/*82*/
{
""
,
TRUE
,
BYTE
,
op2
(
Is
,
E
),
(
const
char
*
)
db_Grp1
},
/*83*/
{
""
,
TRUE
,
LONG
,
op2
(
Ibs
,
E
),
(
const
char
*
)
db_Grp1
},
/*84*/
{
"test"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*85*/
{
"test"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*86*/
{
"xchg"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*87*/
{
"xchg"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*88*/
{
"mov"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*89*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*8a*/
{
"mov"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*8b*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*8c*/
{
"mov"
,
TRUE
,
NONE
,
op2
(
S
,
Ew
),
0
},
/*8d*/
{
"lea"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*8e*/
{
"mov"
,
TRUE
,
NONE
,
op2
(
Ew
,
S
),
0
},
/*8f*/
{
"pop"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
/*90*/
{
"nop"
,
FALSE
,
NONE
,
0
,
0
},
/*91*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*92*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*93*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*94*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*95*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*96*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*97*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*98*/
{
"cbw"
,
FALSE
,
SDEP
,
0
,
"cwde"
},
/* cbw/cwde */
/*99*/
{
"cwd"
,
FALSE
,
SDEP
,
0
,
"cdq"
},
/* cwd/cdq */
/*9a*/
{
"lcall"
,
FALSE
,
NONE
,
op1
(
OS
),
0
},
/*9b*/
{
"wait"
,
FALSE
,
NONE
,
0
,
0
},
/*9c*/
{
"pushf"
,
FALSE
,
LONG
,
0
,
0
},
/*9d*/
{
"popf"
,
FALSE
,
LONG
,
0
,
0
},
/*9e*/
{
"sahf"
,
FALSE
,
NONE
,
0
,
0
},
/*9f*/
{
"lahf"
,
FALSE
,
NONE
,
0
,
0
},
/*a0*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
O
,
A
),
0
},
/*a1*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
O
,
A
),
0
},
/*a2*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
A
,
O
),
0
},
/*a3*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
A
,
O
),
0
},
/*a4*/
{
"movs"
,
FALSE
,
BYTE
,
op2
(
SI
,
DI
),
0
},
/*a5*/
{
"movs"
,
FALSE
,
LONG
,
op2
(
SI
,
DI
),
0
},
/*a6*/
{
"cmps"
,
FALSE
,
BYTE
,
op2
(
SI
,
DI
),
0
},
/*a7*/
{
"cmps"
,
FALSE
,
LONG
,
op2
(
SI
,
DI
),
0
},
/*a8*/
{
"test"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*a9*/
{
"test"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*aa*/
{
"stos"
,
FALSE
,
BYTE
,
op1
(
DI
),
0
},
/*ab*/
{
"stos"
,
FALSE
,
LONG
,
op1
(
DI
),
0
},
/*ac*/
{
"lods"
,
FALSE
,
BYTE
,
op1
(
SI
),
0
},
/*ad*/
{
"lods"
,
FALSE
,
LONG
,
op1
(
SI
),
0
},
/*ae*/
{
"scas"
,
FALSE
,
BYTE
,
op1
(
DI
),
0
},
/*af*/
{
"scas"
,
FALSE
,
LONG
,
op1
(
DI
),
0
},
/*b0*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b1*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b2*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b3*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b4*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b5*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b6*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b7*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b8*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*b9*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*ba*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*bb*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*bc*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*bd*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*be*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*bf*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
I
,
Ri
),
0
},
/*c0*/
{
""
,
TRUE
,
BYTE
,
op2
(
Ib
,
E
),
(
const
char
*
)
db_Grp2
},
/*c1*/
{
""
,
TRUE
,
LONG
,
op2
(
Ib
,
E
),
(
const
char
*
)
db_Grp2
},
/*c2*/
{
"ret"
,
FALSE
,
NONE
,
op1
(
Iw
),
0
},
/*c3*/
{
"ret"
,
FALSE
,
NONE
,
0
,
0
},
/*c4*/
{
"les"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*c5*/
{
"lds"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*c6*/
{
"mov"
,
TRUE
,
BYTE
,
op2
(
I
,
E
),
0
},
/*c7*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
I
,
E
),
0
},
/*c8*/
{
"enter"
,
FALSE
,
NONE
,
op2
(
Iw
,
Ib
),
0
},
/*c9*/
{
"leave"
,
FALSE
,
NONE
,
0
,
0
},
/*ca*/
{
"lret"
,
FALSE
,
NONE
,
op1
(
Iw
),
0
},
/*cb*/
{
"lret"
,
FALSE
,
NONE
,
0
,
0
},
/*cc*/
{
"int"
,
FALSE
,
NONE
,
op1
(
o3
),
0
},
/*cd*/
{
"int"
,
FALSE
,
NONE
,
op1
(
Ib
),
0
},
/*ce*/
{
"into"
,
FALSE
,
NONE
,
0
,
0
},
/*cf*/
{
"iret"
,
FALSE
,
NONE
,
0
,
0
},
/*d0*/
{
""
,
TRUE
,
BYTE
,
op2
(
o1
,
E
),
(
const
char
*
)
db_Grp2
},
/*d1*/
{
""
,
TRUE
,
LONG
,
op2
(
o1
,
E
),
(
const
char
*
)
db_Grp2
},
/*d2*/
{
""
,
TRUE
,
BYTE
,
op2
(
CL
,
E
),
(
const
char
*
)
db_Grp2
},
/*d3*/
{
""
,
TRUE
,
LONG
,
op2
(
CL
,
E
),
(
const
char
*
)
db_Grp2
},
/*d4*/
{
"aam"
,
TRUE
,
NONE
,
0
,
0
},
/*d5*/
{
"aad"
,
TRUE
,
NONE
,
0
,
0
},
/*d6*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*d7*/
{
"xlat"
,
FALSE
,
BYTE
,
op1
(
BX
),
0
},
/*d8*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Esc8
},
/*d9*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Esc9
},
/*da*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Esca
},
/*db*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Escb
},
/*dc*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Escc
},
/*dd*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Escd
},
/*de*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Esce
},
/*df*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Escf
},
/*e0*/
{
"loopne"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*e1*/
{
"loope"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*e2*/
{
"loop"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*e3*/
{
"jcxz"
,
FALSE
,
SDEP
,
op1
(
Db
),
"jecxz"
},
/*e4*/
{
"in"
,
FALSE
,
BYTE
,
op2
(
Ib
,
A
),
0
},
/*e5*/
{
"in"
,
FALSE
,
LONG
,
op2
(
Ib
,
A
)
,
0
},
/*e6*/
{
"out"
,
FALSE
,
BYTE
,
op2
(
A
,
Ib
),
0
},
/*e7*/
{
"out"
,
FALSE
,
LONG
,
op2
(
A
,
Ib
)
,
0
},
/*e8*/
{
"call"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*e9*/
{
"jmp"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*ea*/
{
"ljmp"
,
FALSE
,
NONE
,
op1
(
OS
),
0
},
/*eb*/
{
"jmp"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*ec*/
{
"in"
,
FALSE
,
BYTE
,
op2
(
DX
,
A
),
0
},
/*ed*/
{
"in"
,
FALSE
,
LONG
,
op2
(
DX
,
A
)
,
0
},
/*ee*/
{
"out"
,
FALSE
,
BYTE
,
op2
(
A
,
DX
),
0
},
/*ef*/
{
"out"
,
FALSE
,
LONG
,
op2
(
A
,
DX
)
,
0
},
/*f0*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*f1*/
{
"icebp"
,
FALSE
,
NONE
,
0
,
0
},
/*f2*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*f3*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*f4*/
{
"hlt"
,
FALSE
,
NONE
,
0
,
0
},
/*f5*/
{
"cmc"
,
FALSE
,
NONE
,
0
,
0
},
/*f6*/
{
""
,
TRUE
,
BYTE
,
0
,
(
const
char
*
)
db_Grp3
},
/*f7*/
{
""
,
TRUE
,
LONG
,
0
,
(
const
char
*
)
db_Grp3
},
/*f8*/
{
"clc"
,
FALSE
,
NONE
,
0
,
0
},
/*f9*/
{
"stc"
,
FALSE
,
NONE
,
0
,
0
},
/*fa*/
{
"cli"
,
FALSE
,
NONE
,
0
,
0
},
/*fb*/
{
"sti"
,
FALSE
,
NONE
,
0
,
0
},
/*fc*/
{
"cld"
,
FALSE
,
NONE
,
0
,
0
},
/*fd*/
{
"std"
,
FALSE
,
NONE
,
0
,
0
},
/*fe*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Grp4
},
/*ff*/
{
""
,
TRUE
,
NONE
,
0
,
(
const
char
*
)
db_Grp5
},
};
static
const
struct
inst
db_bad_inst
=
{
"???"
,
FALSE
,
NONE
,
0
,
0
}
;
#define f_mod(byte) ((byte)>>6)
#define f_reg(byte) (((byte)>>3)&0x7)
#define f_rm(byte) ((byte)&0x7)
#define sib_ss(byte) ((byte)>>6)
#define sib_index(byte) (((byte)>>3)&0x7)
#define sib_base(byte) ((byte)&0x7)
struct
i_addr
{
int
is_reg
;
/* if reg, reg number is in 'disp' */
int
disp
;
const
char
*
base
;
const
char
*
index
;
int
ss
;
};
static
const
char
*
const
db_index_reg_16
[
8
]
=
{
"%bx,%si"
,
"%bx,%di"
,
"%bp,%si"
,
"%bp,%di"
,
"%si"
,
"%di"
,
"%bp"
,
"%bx"
};
static
const
char
*
const
db_reg
[
5
][
8
]
=
{
/*BYTE*/
{
"%al"
,
"%cl"
,
"%dl"
,
"%bl"
,
"%ah"
,
"%ch"
,
"%dh"
,
"%bh"
},
/*WORD*/
{
"%ax"
,
"%cx"
,
"%dx"
,
"%bx"
,
"%sp"
,
"%bp"
,
"%si"
,
"%di"
},
/*LONG*/
{
"%eax"
,
"%ecx"
,
"%edx"
,
"%ebx"
,
"%esp"
,
"%ebp"
,
"%esi"
,
"%edi"
},
/*QUAD*/
{
"%mm0"
,
"%mm1"
,
"%mm2"
,
"%mm3"
,
"%mm4"
,
"%mm5"
,
"%mm6"
,
"%mm7"
},
/*DQUA*/
{
"%xmm0"
,
"%xmm1"
,
"%xmm2"
,
"%xmm3"
,
"%xmm4"
,
"%xmm5"
,
"%xmm6"
,
"%xmm7"
}
};
static
const
char
*
const
db_seg_reg
[
8
]
=
{
"%es"
,
"%cs"
,
"%ss"
,
"%ds"
,
"%fs"
,
"%gs"
,
""
,
""
};
/*
* lengths for size attributes
*/
static
const
int
db_lengths
[]
=
{
1
,
/* BYTE */
2
,
/* WORD */
4
,
/* LONG */
8
,
/* QUAD */
16
,
/* DQUA */
4
,
/* SNGL */
8
,
/* DBLR */
10
,
/* EXTR */
};
static
unsigned
int
db_get_task_value
(
const
ADDRESS64
*
addr
,
int
size
,
int
is_signed
)
{
unsigned
int
result
=
0
;
char
buffer
[
4
];
if
(
size
!=
1
&&
size
!=
2
&&
size
!=
4
)
{
dbg_printf
(
"Illegal size specified
\n
"
);
}
else
{
dbg_read_memory
(
memory_to_linear_addr
(
addr
),
buffer
,
size
);
switch
(
size
)
{
case
4
:
if
(
is_signed
)
result
=
(
unsigned
int
)
*
(
int
*
)
buffer
;
else
result
=
*
(
unsigned
int
*
)
buffer
;
break
;
case
2
:
if
(
is_signed
)
result
=
(
unsigned
int
)
*
(
short
int
*
)
buffer
;
else
result
=
*
(
unsigned
short
int
*
)
buffer
;
break
;
case
1
:
if
(
is_signed
)
result
=
(
unsigned
int
)
*
(
char
*
)
buffer
;
else
result
=
*
(
unsigned
char
*
)
buffer
;
break
;
}
}
return
result
;
}
#define get_value_inc(result, addr, size, is_signed) \
result = db_get_task_value((addr), (size), (is_signed)); \
if (!db_disasm_16) (addr)->Offset += (size); \
else (addr)->Offset = ((addr)->Offset + (size)) & 0xffff;
/*
* Read address at location and return updated location.
*/
static
void
db_read_address
(
ADDRESS64
*
addr
,
int
short_addr
,
int
regmodrm
,
struct
i_addr
*
addrp
)
{
int
mod
,
rm
,
sib
,
index
,
disp
;
mod
=
f_mod
(
regmodrm
);
rm
=
f_rm
(
regmodrm
);
if
(
mod
==
3
)
{
addrp
->
is_reg
=
TRUE
;
addrp
->
disp
=
rm
;
return
;
}
addrp
->
is_reg
=
FALSE
;
addrp
->
index
=
0
;
if
(
short_addr
)
{
addrp
->
index
=
0
;
addrp
->
ss
=
0
;
switch
(
mod
)
{
case
0
:
if
(
rm
==
6
)
{
get_value_inc
(
disp
,
addr
,
2
,
TRUE
);
addrp
->
disp
=
disp
;
addrp
->
base
=
0
;
}
else
{
addrp
->
disp
=
0
;
addrp
->
base
=
db_index_reg_16
[
rm
];
}
break
;
case
1
:
get_value_inc
(
disp
,
addr
,
1
,
TRUE
);
addrp
->
disp
=
disp
;
addrp
->
base
=
db_index_reg_16
[
rm
];
break
;
case
2
:
get_value_inc
(
disp
,
addr
,
2
,
TRUE
);
addrp
->
disp
=
disp
;
addrp
->
base
=
db_index_reg_16
[
rm
];
break
;
}
}
else
{
if
(
mod
!=
3
&&
rm
==
4
)
{
get_value_inc
(
sib
,
addr
,
1
,
FALSE
);
rm
=
sib_base
(
sib
);
index
=
sib_index
(
sib
);
if
(
index
!=
4
)
addrp
->
index
=
db_reg
[
LONG
][
index
];
addrp
->
ss
=
sib_ss
(
sib
);
}
switch
(
mod
)
{
case
0
:
if
(
rm
==
5
)
{
get_value_inc
(
addrp
->
disp
,
addr
,
4
,
FALSE
);
addrp
->
base
=
0
;
}
else
{
addrp
->
disp
=
0
;
addrp
->
base
=
db_reg
[
LONG
][
rm
];
}
break
;
case
1
:
get_value_inc
(
disp
,
addr
,
1
,
TRUE
);
addrp
->
disp
=
disp
;
addrp
->
base
=
db_reg
[
LONG
][
rm
];
break
;
case
2
:
get_value_inc
(
disp
,
addr
,
4
,
FALSE
);
addrp
->
disp
=
disp
;
addrp
->
base
=
db_reg
[
LONG
][
rm
];
break
;
}
}
}
static
void
db_task_printsym
(
unsigned
int
addr
,
int
size
)
{
ADDRESS64
a
;
a
.
Mode
=
AddrModeFlat
;
a
.
Offset
=
addr
;
print_address
(
&
a
,
TRUE
);
}
static
void
db_print_address
(
const
char
*
seg
,
int
size
,
struct
i_addr
*
addrp
,
int
byref
)
{
if
(
addrp
->
is_reg
)
{
dbg_printf
(
"%s"
,
db_reg
[
size
][
addrp
->
disp
]);
return
;
}
if
(
seg
)
{
dbg_printf
(
"%s:"
,
seg
);
}
if
(
addrp
->
base
!=
0
||
addrp
->
index
!=
0
)
{
dbg_printf
(
"0x%x("
,
addrp
->
disp
);
if
(
addrp
->
base
)
dbg_printf
(
"%s"
,
addrp
->
base
);
if
(
addrp
->
index
)
dbg_printf
(
",%s,%d"
,
addrp
->
index
,
1
<<
addrp
->
ss
);
dbg_printf
(
")"
);
}
else
{
/* try to get destination of indirect call
does not work for segmented addresses */
if
(
!
seg
&&
byref
)
{
void
*
a1
;
void
*
a2
;
dbg_printf
(
"0x%x -> "
,
addrp
->
disp
);
if
(
!
dbg_read_memory
((
void
*
)(
INT_PTR
)
addrp
->
disp
,
&
a1
,
sizeof
(
a1
)))
{
dbg_printf
(
"(invalid source)"
);
}
else
if
(
!
dbg_read_memory
(
a1
,
&
a2
,
sizeof
(
a2
)))
{
dbg_printf
(
"(invalid destination)"
);
}
else
{
db_task_printsym
((
ULONG_PTR
)
a1
,
0
);
}
}
else
db_task_printsym
(
addrp
->
disp
,
size
);
}
}
/*
* Disassemble floating-point ("escape") instruction
* and return updated location.
*/
static
void
db_disasm_esc
(
ADDRESS64
*
addr
,
int
inst
,
int
short_addr
,
int
size
,
const
char
*
seg
)
{
int
regmodrm
;
const
struct
finst
*
fp
;
int
mod
;
struct
i_addr
address
;
const
char
*
name
;
get_value_inc
(
regmodrm
,
addr
,
1
,
FALSE
);
if
(
!
db_display
)
{
return
;
}
fp
=
&
db_Esc_inst
[
inst
-
0xd8
][
f_reg
(
regmodrm
)];
mod
=
f_mod
(
regmodrm
);
if
(
mod
!=
3
)
{
const
char
*
p
;
/*
* Normal address modes.
*/
db_read_address
(
addr
,
short_addr
,
regmodrm
,
&
address
);
dbg_printf
(
"%s"
,
fp
->
f_name
);
switch
(
fp
->
f_size
)
{
case
SNGL
:
p
=
"s"
;
break
;
case
DBLR
:
p
=
"l"
;
break
;
case
EXTR
:
p
=
"t"
;
break
;
case
WORD
:
p
=
"s"
;
break
;
case
LONG
:
p
=
"l"
;
break
;
case
QUAD
:
p
=
"q"
;
break
;
default:
p
=
""
;
break
;
}
dbg_printf
(
"%s
\t
"
,
p
);
db_print_address
(
seg
,
BYTE
,
&
address
,
0
);
}
else
{
/*
* 'reg-reg' - special formats
*/
switch
(
fp
->
f_rrmode
)
{
case
op2
(
ST
,
STI
):
name
=
(
fp
->
f_rrname
)
?
fp
->
f_rrname
:
fp
->
f_name
;
dbg_printf
(
"%s
\t
%%st,%%st(%d)"
,
name
,
f_rm
(
regmodrm
));
break
;
case
op2
(
STI
,
ST
):
name
=
(
fp
->
f_rrname
)
?
fp
->
f_rrname
:
fp
->
f_name
;
dbg_printf
(
"%s
\t
%%st(%d),%%st"
,
name
,
f_rm
(
regmodrm
));
break
;
case
op1
(
STI
):
name
=
(
fp
->
f_rrname
)
?
fp
->
f_rrname
:
fp
->
f_name
;
dbg_printf
(
"%s
\t
%%st(%d)"
,
name
,
f_rm
(
regmodrm
));
break
;
case
op1
(
X
):
dbg_printf
(
"%s"
,
((
char
*
const
*
)
fp
->
f_rrname
)[
f_rm
(
regmodrm
)]);
break
;
case
op1
(
XA
):
dbg_printf
(
"%s
\t
%%ax"
,
((
char
*
const
*
)
fp
->
f_rrname
)[
f_rm
(
regmodrm
)]);
break
;
default:
dbg_printf
(
"<bad instruction>"
);
break
;
}
}
}
/***********************************************************************
* disasm_one_insn
*
* Disassemble instruction at 'addr'. addr is changed to point to the
* start of the next instruction.
*/
void
be_i386_disasm_one_insn
(
ADDRESS64
*
addr
,
int
display
)
{
int
inst
;
int
size
;
int
short_addr
;
const
char
*
seg
;
const
struct
inst
*
ip
;
const
char
*
i_name
;
int
i_size
;
int
i_mode
;
int
regmodrm
=
0
;
BOOL
first
;
int
displ
;
int
prefix
;
int
imm
;
int
len
;
struct
i_addr
address
;
/*
* Set this so we can suppress the printout if we need to.
*/
db_display
=
display
;
switch
(
addr
->
Mode
)
{
case
AddrModeReal
:
case
AddrMode1616
:
db_disasm_16
=
1
;
break
;
default:
db_disasm_16
=
0
;
break
;
}
get_value_inc
(
inst
,
addr
,
1
,
FALSE
);
if
(
db_disasm_16
)
{
short_addr
=
TRUE
;
size
=
WORD
;
}
else
{
short_addr
=
FALSE
;
size
=
LONG
;
}
seg
=
0
;
/*
* Get prefixes
*/
prefix
=
TRUE
;
do
{
switch
(
inst
)
{
case
0x66
:
/* data16 */
if
(
size
==
LONG
)
size
=
WORD
;
else
size
=
LONG
;
break
;
case
0x67
:
short_addr
=
!
short_addr
;
break
;
case
0x26
:
seg
=
"%es"
;
break
;
case
0x36
:
seg
=
"%ss"
;
break
;
case
0x2e
:
seg
=
"%cs"
;
break
;
case
0x3e
:
seg
=
"%ds"
;
break
;
case
0x64
:
seg
=
"%fs"
;
break
;
case
0x65
:
seg
=
"%gs"
;
break
;
case
0xf0
:
if
(
db_display
)
dbg_printf
(
"lock "
);
break
;
case
0xf2
:
if
(
db_display
)
dbg_printf
(
"repne "
);
break
;
case
0xf3
:
if
(
db_display
)
dbg_printf
(
"repe "
);
/* XXX repe VS rep */
break
;
default:
prefix
=
FALSE
;
break
;
}
if
(
prefix
)
{
get_value_inc
(
inst
,
addr
,
1
,
FALSE
);
}
}
while
(
prefix
);
if
(
inst
>=
0xd8
&&
inst
<=
0xdf
)
{
db_disasm_esc
(
addr
,
inst
,
short_addr
,
size
,
seg
);
return
;
}
if
(
inst
==
0x0f
)
{
get_value_inc
(
inst
,
addr
,
1
,
FALSE
);
ip
=
db_inst_0f
[
inst
>>
4
];
if
(
ip
==
0
)
{
ip
=
&
db_bad_inst
;
}
else
{
ip
=
&
ip
[
inst
&
0xf
];
}
}
else
ip
=
&
db_inst_table
[
inst
];
if
(
ip
->
i_has_modrm
)
{
get_value_inc
(
regmodrm
,
addr
,
1
,
FALSE
);
db_read_address
(
addr
,
short_addr
,
regmodrm
,
&
address
);
}
i_name
=
ip
->
i_name
;
i_size
=
ip
->
i_size
;
i_mode
=
ip
->
i_mode
;
if
(
ip
->
i_extra
==
(
const
char
*
)
db_Grp1
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp2
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp6
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp7
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp8
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp10
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp11
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp12
)
{
i_name
=
((
const
char
*
const
*
)
ip
->
i_extra
)[
f_reg
(
regmodrm
)];
}
else
if
(
ip
->
i_extra
==
(
const
char
*
)
db_Grp3
)
{
ip
=
(
const
struct
inst
*
)
ip
->
i_extra
;
ip
=
&
ip
[
f_reg
(
regmodrm
)];
i_name
=
ip
->
i_name
;
i_mode
=
ip
->
i_mode
;
}
else
if
(
ip
->
i_extra
==
(
const
char
*
)
db_Grp4
||
ip
->
i_extra
==
(
const
char
*
)
db_Grp5
)
{
ip
=
(
const
struct
inst
*
)
ip
->
i_extra
;
ip
=
&
ip
[
f_reg
(
regmodrm
)];
i_name
=
ip
->
i_name
;
i_mode
=
ip
->
i_mode
;
i_size
=
ip
->
i_size
;
}
if
(
i_size
==
SDEP
)
{
if
(
db_display
)
{
if
(
size
==
WORD
)
dbg_printf
(
"%s"
,
i_name
);
else
dbg_printf
(
"%s"
,
ip
->
i_extra
);
}
}
else
{
if
(
db_display
)
{
dbg_printf
(
"%s"
,
i_name
);
}
if
(
i_size
!=
NONE
)
{
if
(
i_size
==
BYTE
)
{
if
(
db_display
)
{
dbg_printf
(
"b"
);
}
size
=
BYTE
;
}
else
if
(
i_size
==
WORD
)
{
if
(
db_display
)
{
dbg_printf
(
"w"
);
}
size
=
WORD
;
}
else
if
(
size
==
WORD
)
{
if
(
db_display
)
{
dbg_printf
(
"w"
);
}
}
else
{
if
(
db_display
)
{
dbg_printf
(
"l"
);
}
}
}
}
if
(
db_display
)
{
dbg_printf
(
"
\t
"
);
}
for
(
first
=
TRUE
;
i_mode
!=
0
;
i_mode
>>=
8
,
first
=
FALSE
)
{
if
(
!
first
&&
db_display
)
dbg_printf
(
","
);
switch
(
i_mode
&
0xFF
)
{
case
E
:
if
(
db_display
)
{
db_print_address
(
seg
,
size
,
&
address
,
0
);
}
break
;
case
Eind
:
if
(
db_display
)
{
dbg_printf
(
"*"
);
db_print_address
(
seg
,
size
,
&
address
,
1
);
}
break
;
case
Ew
:
if
(
db_display
)
{
db_print_address
(
seg
,
WORD
,
&
address
,
0
);
}
break
;
case
Eb
:
if
(
db_display
)
{
db_print_address
(
seg
,
BYTE
,
&
address
,
0
);
}
break
;
case
R
:
if
(
db_display
)
{
dbg_printf
(
"%s"
,
db_reg
[
size
][
f_reg
(
regmodrm
)]);
}
break
;
case
MX
:
if
(
db_display
)
{
dbg_printf
(
"%%mm%d"
,
f_reg
(
regmodrm
));
}
break
;
case
EMX
:
if
(
db_display
)
{
db_print_address
(
seg
,
QUAD
,
&
address
,
0
);
}
break
;
case
XMM
:
if
(
db_display
)
{
dbg_printf
(
"%%xmm%d"
,
f_reg
(
regmodrm
));
}
break
;
case
EXMM
:
if
(
db_display
)
{
db_print_address
(
seg
,
DQUA
,
&
address
,
0
);
}
break
;
case
Rw
:
if
(
db_display
)
{
dbg_printf
(
"%s"
,
db_reg
[
WORD
][
f_reg
(
regmodrm
)]);
}
break
;
case
Ri
:
if
(
db_display
)
{
dbg_printf
(
"%s"
,
db_reg
[
size
][
f_rm
(
inst
)]);
}
break
;
case
S
:
if
(
db_display
)
{
dbg_printf
(
"%s"
,
db_seg_reg
[
f_reg
(
regmodrm
)]);
}
break
;
case
Si
:
if
(
db_display
)
{
dbg_printf
(
"%s"
,
db_seg_reg
[
f_reg
(
inst
)]);
}
break
;
case
A
:
if
(
db_display
)
{
dbg_printf
(
"%s"
,
db_reg
[
size
][
0
]);
/* acc */
}
break
;
case
BX
:
if
(
db_display
)
{
if
(
seg
)
dbg_printf
(
"%s:"
,
seg
);
dbg_printf
(
"(%s)"
,
short_addr
?
"%bx"
:
"%ebx"
);
}
break
;
case
CL
:
if
(
db_display
)
{
dbg_printf
(
"%%cl"
);
}
break
;
case
DX
:
if
(
db_display
)
{
dbg_printf
(
"%%dx"
);
}
break
;
case
SI
:
if
(
db_display
)
{
if
(
seg
)
dbg_printf
(
"%s:"
,
seg
);
dbg_printf
(
"(%s)"
,
short_addr
?
"%si"
:
"%esi"
);
}
break
;
case
DI
:
if
(
db_display
)
{
dbg_printf
(
"%%es:(%s)"
,
short_addr
?
"%di"
:
"%edi"
);
}
break
;
case
CR
:
if
(
db_display
)
{
dbg_printf
(
"%%cr%d"
,
f_reg
(
regmodrm
));
}
break
;
case
DR
:
if
(
db_display
)
{
dbg_printf
(
"%%dr%d"
,
f_reg
(
regmodrm
));
}
break
;
case
TR
:
if
(
db_display
)
{
dbg_printf
(
"%%tr%d"
,
f_reg
(
regmodrm
));
}
break
;
case
I
:
len
=
db_lengths
[
size
];
get_value_inc
(
imm
,
addr
,
len
,
FALSE
);
/* unsigned */
if
(
db_display
)
{
dbg_printf
(
"$0x%x"
,
imm
);
}
break
;
case
Is
:
len
=
db_lengths
[
size
];
get_value_inc
(
imm
,
addr
,
len
,
TRUE
);
/* signed */
if
(
db_display
)
{
dbg_printf
(
"$%d"
,
imm
);
}
break
;
case
Ib
:
get_value_inc
(
imm
,
addr
,
1
,
FALSE
);
/* unsigned */
if
(
db_display
)
{
dbg_printf
(
"$0x%x"
,
imm
);
}
break
;
case
Ibs
:
get_value_inc
(
imm
,
addr
,
1
,
TRUE
);
/* signed */
if
(
db_display
)
{
dbg_printf
(
"$%d"
,
imm
);
}
break
;
case
Iw
:
get_value_inc
(
imm
,
addr
,
2
,
FALSE
);
/* unsigned */
if
(
db_display
)
{
dbg_printf
(
"$0x%x"
,
imm
);
}
break
;
case
Il
:
get_value_inc
(
imm
,
addr
,
4
,
FALSE
);
if
(
db_display
)
{
dbg_printf
(
"$0x%x"
,
imm
);
}
break
;
case
O
:
if
(
short_addr
)
{
get_value_inc
(
displ
,
addr
,
2
,
TRUE
);
}
else
{
get_value_inc
(
displ
,
addr
,
4
,
TRUE
);
}
if
(
!
db_display
)
{
break
;
}
if
(
seg
)
dbg_printf
(
"%s:0x%x"
,
seg
,
displ
);
else
db_task_printsym
(
displ
,
short_addr
?
WORD
:
LONG
);
break
;
case
Db
:
get_value_inc
(
displ
,
addr
,
1
,
TRUE
);
if
(
!
db_display
)
{
break
;
}
if
(
size
==
WORD
)
{
/* offset only affects low 16 bits */
displ
=
(
addr
->
Offset
&
0xffff0000
)
|
((
addr
->
Offset
+
displ
)
&
0xffff
);
}
else
displ
+=
addr
->
Offset
;
db_task_printsym
(
displ
,
size
);
break
;
case
Dl
:
if
(
size
==
WORD
)
{
get_value_inc
(
displ
,
addr
,
2
,
TRUE
);
/* Offset only affects low 16 bits */
displ
=
(
addr
->
Offset
&
0xffff0000
)
|
((
addr
->
Offset
+
displ
)
&
0xffff
);
}
else
{
get_value_inc
(
displ
,
addr
,
4
,
TRUE
);
displ
+=
addr
->
Offset
;
}
if
(
!
db_display
)
{
break
;
}
db_task_printsym
(
displ
,
size
);
break
;
case
o1
:
if
(
db_display
)
{
dbg_printf
(
"$1"
);
}
break
;
case
o3
:
if
(
db_display
)
{
dbg_printf
(
"$3"
);
}
break
;
case
OS
:
{
ADDRESS64
address
;
get_value_inc
(
address
.
Offset
,
addr
,
/* offset */
short_addr
?
2
:
4
,
FALSE
);
get_value_inc
(
address
.
Segment
,
addr
,
/* segment */
2
,
FALSE
);
dbg_curr_process
->
be_cpu
->
build_addr
(
dbg_curr_thread
->
handle
,
&
dbg_context
,
&
address
,
address
.
Segment
,
address
.
Offset
);
if
(
db_display
)
{
print_address
(
&
address
,
TRUE
);
}
}
break
;
}
}
}
#endif
/* __i386__ */
programs/winedbg/db_disasm64.c
deleted
100644 → 0
View file @
7bc94bc8
/*-
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*
* Instruction disassembler.
*/
/* <Wine specific wrappers> */
#include <stdio.h>
#include "debugger.h"
#if defined(__GNUC__) && (__GNUC__ >= 3)
static
int
WINAPIV
(
*
db_printf
)(
const
char
*
format
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
#else
static
int
WINAPIV
(
*
db_printf
)(
const
char
*
format
,
...);
#endif
static
int
WINAPIV
no_printf
(
const
char
*
format
,
...)
{
return
0
;}
typedef
DWORD_PTR
db_addr_t
;
typedef
BOOL
boolean_t
;
static
ULONG64
db_get_value
(
db_addr_t
addr
,
int
size
,
int
is_signed
)
{
ULONG64
result
=
0
;
char
buffer
[
8
];
if
(
size
!=
1
&&
size
!=
2
&&
size
!=
4
&&
size
!=
8
)
{
db_printf
(
"Illegal size specified
\n
"
);
}
else
if
(
dbg_read_memory
((
void
*
)
addr
,
buffer
,
size
))
{
switch
(
size
)
{
case
8
:
if
(
is_signed
)
result
=
(
ULONG64
)
*
(
LONG64
*
)
buffer
;
else
result
=
*
(
ULONG64
*
)
buffer
;
break
;
case
4
:
if
(
is_signed
)
result
=
(
ULONG
)
*
(
LONG
*
)
buffer
;
else
result
=
*
(
ULONG64
*
)
buffer
;
break
;
case
2
:
if
(
is_signed
)
result
=
(
unsigned
int
)
*
(
short
int
*
)
buffer
;
else
result
=
*
(
unsigned
short
int
*
)
buffer
;
break
;
case
1
:
if
(
is_signed
)
result
=
(
unsigned
int
)
*
(
char
*
)
buffer
;
else
result
=
*
(
unsigned
char
*
)
buffer
;
break
;
}
}
return
result
;
}
#define DB_STGY_ANY 0
#define DB_STGY_XTRN 0
static
void
db_printsym
(
db_addr_t
addr
,
unsigned
unused
)
{
if
(
db_printf
!=
no_printf
)
{
ADDRESS64
a
;
a
.
Mode
=
AddrModeFlat
;
a
.
Offset
=
addr
;
print_address
(
&
a
,
FALSE
);
}
}
/* </Wine specific wrappers> */
/*
* Size attributes
*/
#define BYTE 0
#define WORD 1
#define LONG 2
#define QUAD 3
#define SNGL 4
#define DBLR 5
#define EXTR 6
#define SDEP 7
#define NONE 8
/*
* REX prefix and bits
*/
#define REX_B 1
#define REX_X 2
#define REX_R 4
#define REX_W 8
#define REX 0x40
/*
* Addressing modes
*/
#define E 1
/* general effective address */
#define Eind 2
/* indirect address (jump, call) */
#define Ew 3
/* address, word size */
#define Eb 4
/* address, byte size */
#define R 5
/* register, in 'reg' field */
#define Rw 6
/* word register, in 'reg' field */
#define Ri 7
/* register in instruction */
#define S 8
/* segment reg, in 'reg' field */
#define Si 9
/* segment reg, in instruction */
#define A 10
/* accumulator */
#define BX 11
/* (bx) */
#define CL 12
/* cl, for shifts */
#define DX 13
/* dx, for IO */
#define SI 14
/* si */
#define DI 15
/* di */
#define CR 16
/* control register */
#define DR 17
/* debug register */
#define TR 18
/* test register */
#define I 19
/* immediate, unsigned */
#define Is 20
/* immediate, signed */
#define Ib 21
/* byte immediate, unsigned */
#define Ibs 22
/* byte immediate, signed */
#define Iw 23
/* word immediate, unsigned */
#define Ilq 24
/* long/quad immediate, unsigned */
#define O 25
/* direct address */
#define Db 26
/* byte displacement from EIP */
#define Dl 27
/* long displacement from EIP */
#define o1 28
/* constant 1 */
#define o3 29
/* constant 3 */
#define OS 30
/* immediate offset/segment */
#define ST 31
/* FP stack top */
#define STI 32
/* FP stack */
#define X 33
/* extended FP op */
#define XA 34
/* for 'fstcw %ax' */
#define El 35
/* address, long/quad size */
#define Ril 36
/* long register in instruction */
#define Iba 37
/* byte immediate, don't print if 0xa */
#define EL 38
/* address, explicitly long size */
/* Wine extensions */
#define MX 39
/* special register (MMX reg %mm0-7) */
#define EMX 40
/* special register (MMX reg %mm0-7) */
#define XMM 41
/* special register (floating point reg %xmm0-7) */
#define EXMM 42
/* special register (floating point reg %xmm0-7) */
struct
inst
{
const
char
*
i_name
;
/* name */
short
i_has_modrm
;
/* has regmodrm byte */
short
i_size
;
/* operand size */
int
i_mode
;
/* addressing modes */
const
void
*
i_extra
;
/* pointer to extra opcode table */
};
#define op1(x) (x)
#define op2(x,y) ((x)|((y)<<8))
#define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
struct
finst
{
const
char
*
f_name
;
/* name for memory instruction */
int
f_size
;
/* size for memory instruction */
int
f_rrmode
;
/* mode for rr instruction */
const
void
*
f_rrname
;
/* name for rr instruction
(or pointer to table) */
};
static
const
char
*
const
db_Grp6
[]
=
{
"sldt"
,
"str"
,
"lldt"
,
"ltr"
,
"verr"
,
"verw"
,
""
,
""
};
static
const
char
*
const
db_Grp7
[]
=
{
"sgdt"
,
"sidt"
,
"lgdt"
,
"lidt"
,
"smsw"
,
""
,
"lmsw"
,
"invlpg"
};
static
const
char
*
const
db_Grp8
[]
=
{
""
,
""
,
""
,
""
,
"bt"
,
"bts"
,
"btr"
,
"btc"
};
static
const
char
*
const
db_Grp9
[]
=
{
""
,
"cmpxchg8b"
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Grp15
[]
=
{
"fxsave"
,
"fxrstor"
,
"ldmxcsr"
,
"stmxcsr"
,
""
,
""
,
""
,
"clflush"
};
static
const
char
*
const
db_Grp15b
[]
=
{
""
,
""
,
""
,
""
,
""
,
"lfence"
,
"mfence"
,
"sfence"
};
static
const
struct
inst
db_inst_0f0x
[]
=
{
/*00*/
{
""
,
TRUE
,
NONE
,
op1
(
Ew
),
db_Grp6
},
/*01*/
{
""
,
TRUE
,
NONE
,
op1
(
Ew
),
db_Grp7
},
/*02*/
{
"lar"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*03*/
{
"lsl"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*04*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*05*/
{
"syscall"
,
FALSE
,
NONE
,
0
,
0
},
/*06*/
{
"clts"
,
FALSE
,
NONE
,
0
,
0
},
/*07*/
{
"sysret"
,
FALSE
,
NONE
,
0
,
0
},
/*08*/
{
"invd"
,
FALSE
,
NONE
,
0
,
0
},
/*09*/
{
"wbinvd"
,
FALSE
,
NONE
,
0
,
0
},
/*0a*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0b*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0c*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0d*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*0f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
db_inst_0f1x
[]
=
{
/*10*/
{
"movups"
,
TRUE
,
NONE
,
op2
(
E
,
XMM
),
0
},
/*11*/
{
"movups"
,
TRUE
,
NONE
,
op2
(
XMM
,
E
),
0
},
/*12*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*13*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*14*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*15*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*16*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*17*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*18*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*19*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*1a*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*1b*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*1c*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*1d*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*1e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*1f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
db_inst_0f2x
[]
=
{
/*20*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
CR
,
El
),
0
},
/*21*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
DR
,
El
),
0
},
/*22*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
El
,
CR
),
0
},
/*23*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
El
,
DR
),
0
},
/*24*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
TR
,
El
),
0
},
/*25*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*26*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
El
,
TR
),
0
},
/*27*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*28*/
{
"movaps"
,
TRUE
,
NONE
,
op2
(
E
,
XMM
),
0
},
/*29*/
{
"movaps"
,
TRUE
,
NONE
,
op2
(
XMM
,
E
),
0
},
/*2a*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2b*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2c*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2d*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
db_inst_0f3x
[]
=
{
/*30*/
{
"wrmsr"
,
FALSE
,
NONE
,
0
,
0
},
/*31*/
{
"rdtsc"
,
FALSE
,
NONE
,
0
,
0
},
/*32*/
{
"rdmsr"
,
FALSE
,
NONE
,
0
,
0
},
/*33*/
{
"rdpmc"
,
FALSE
,
NONE
,
0
,
0
},
/*34*/
{
"sysenter"
,
FALSE
,
NONE
,
0
,
0
},
/*35*/
{
"sysexit"
,
FALSE
,
NONE
,
0
,
0
},
/*36*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*37*/
{
"getsec"
,
FALSE
,
NONE
,
0
,
0
},
/*38*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*39*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3a*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3b*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3c*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3d*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
};
static
const
struct
inst
db_inst_0f4x
[]
=
{
/*40*/
{
"cmovo"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*41*/
{
"cmovno"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*42*/
{
"cmovb"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*43*/
{
"cmovnb"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*44*/
{
"cmovz"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*45*/
{
"cmovnz"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*46*/
{
"cmovbe"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*47*/
{
"cmovnbe"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*48*/
{
"cmovs"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*49*/
{
"cmovns"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4a*/
{
"cmovp"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4b*/
{
"cmovnp"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4c*/
{
"cmovl"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4d*/
{
"cmovnl"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4e*/
{
"cmovle"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
/*4f*/
{
"cmovnle"
,
TRUE
,
NONE
,
op2
(
E
,
R
),
0
},
};
static
const
struct
inst
db_inst_0f5x
[]
=
{
/*50*/
{
"movmskps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
R
),
0
},
/*51*/
{
"sqrtps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*52*/
{
"rsqrtps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*53*/
{
"rcpps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*54*/
{
"andps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*55*/
{
"andnps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*56*/
{
"orps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*57*/
{
"xorps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*58*/
{
"addps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*59*/
{
"mulps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5a*/
{
"cvtps2pd"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5b*/
{
"cvtdq2ps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5c*/
{
"subps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5d*/
{
"minps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5e*/
{
"divps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
/*5f*/
{
"maxps"
,
TRUE
,
NONE
,
op2
(
EXMM
,
XMM
),
0
},
};
static
const
struct
inst
db_inst_0f6x
[]
=
{
/*60*/
{
"punpcklbw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*61*/
{
"punpcklwd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*62*/
{
"punpckldq"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*63*/
{
"packsswb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*64*/
{
"pcmpgtb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*65*/
{
"pcmpgtw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*66*/
{
"pcmpgtd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*67*/
{
"packuswb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*68*/
{
"punpckhbw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*69*/
{
"punpckhwd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6a*/
{
"punpckhdq"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6b*/
{
"packssdw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6c*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*6d*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*6e*/
{
"movd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*6f*/
{
"movq"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
};
static
const
struct
inst
db_inst_0f7x
[]
=
{
/*70*/
{
"pshufw"
,
TRUE
,
NONE
,
op2
(
MX
,
EMX
),
0
},
/*71*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/* FIXME: grp 12 */
/*72*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/* FIXME: grp 13 */
/*73*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/* FIXME: grp 14 */
/*74*/
{
"pcmpeqb"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*75*/
{
"pcmpeqw"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*76*/
{
"pcmpeqd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*77*/
{
"emms"
,
FALSE
,
NONE
,
0
,
0
},
/*78*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*79*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7a*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7b*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7c*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7d*/
{
"(bad)"
,
TRUE
,
NONE
,
0
,
0
},
/*7e*/
{
"movd"
,
TRUE
,
NONE
,
op2
(
E
,
MX
),
0
},
/*7f*/
{
"movq"
,
TRUE
,
NONE
,
op2
(
EMX
,
MX
),
0
},
};
static
const
struct
inst
db_inst_0f8x
[]
=
{
/*80*/
{
"jo"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*81*/
{
"jno"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*82*/
{
"jb"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*83*/
{
"jnb"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*84*/
{
"jz"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*85*/
{
"jnz"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*86*/
{
"jbe"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*87*/
{
"jnbe"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*88*/
{
"js"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*89*/
{
"jns"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8a*/
{
"jp"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8b*/
{
"jnp"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8c*/
{
"jl"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8d*/
{
"jnl"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8e*/
{
"jle"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*8f*/
{
"jnle"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
};
static
const
struct
inst
db_inst_0f9x
[]
=
{
/*90*/
{
"seto"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*91*/
{
"setno"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*92*/
{
"setb"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*93*/
{
"setnb"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*94*/
{
"setz"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*95*/
{
"setnz"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*96*/
{
"setbe"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*97*/
{
"setnbe"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*98*/
{
"sets"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*99*/
{
"setns"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9a*/
{
"setp"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9b*/
{
"setnp"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9c*/
{
"setl"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9d*/
{
"setnl"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9e*/
{
"setle"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
/*9f*/
{
"setnle"
,
TRUE
,
NONE
,
op1
(
Eb
),
0
},
};
static
const
struct
inst
db_inst_0fax
[]
=
{
/*a0*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*a1*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*a2*/
{
"cpuid"
,
FALSE
,
NONE
,
0
,
0
},
/*a3*/
{
"bt"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*a4*/
{
"shld"
,
TRUE
,
LONG
,
op3
(
Ib
,
R
,
E
),
0
},
/*a5*/
{
"shld"
,
TRUE
,
LONG
,
op3
(
CL
,
R
,
E
),
0
},
/*a6*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*a7*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*a8*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*a9*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*aa*/
{
"rsm"
,
FALSE
,
NONE
,
0
,
0
},
/*ab*/
{
"bts"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*ac*/
{
"shrd"
,
TRUE
,
LONG
,
op3
(
Ib
,
R
,
E
),
0
},
/*ad*/
{
"shrd"
,
TRUE
,
LONG
,
op3
(
CL
,
R
,
E
),
0
},
/*ae*/
{
""
,
TRUE
,
LONG
,
op1
(
E
),
db_Grp15
},
/*af*/
{
"imul"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
};
static
const
struct
inst
db_inst_0fbx
[]
=
{
/*b0*/
{
"cmpxchg"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*b0*/
{
"cmpxchg"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*b2*/
{
"lss"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b3*/
{
"btr"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*b4*/
{
"lfs"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b5*/
{
"lgs"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*b6*/
{
"movzb"
,
TRUE
,
LONG
,
op2
(
Eb
,
R
),
0
},
/*b7*/
{
"movzw"
,
TRUE
,
LONG
,
op2
(
Ew
,
R
),
0
},
/*b8*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*b9*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*ba*/
{
""
,
TRUE
,
LONG
,
op2
(
Ib
,
E
),
db_Grp8
},
/*bb*/
{
"btc"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*bc*/
{
"bsf"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*bd*/
{
"bsr"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*be*/
{
"movsb"
,
TRUE
,
LONG
,
op2
(
Eb
,
R
),
0
},
/*bf*/
{
"movsw"
,
TRUE
,
LONG
,
op2
(
Ew
,
R
),
0
},
};
static
const
struct
inst
db_inst_0fcx
[]
=
{
/*c0*/
{
"xadd"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*c1*/
{
"xadd"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*c2*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c3*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c4*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c5*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c6*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*c7*/
{
""
,
TRUE
,
NONE
,
op1
(
E
),
db_Grp9
},
/*c8*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
/*c9*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
/*ca*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
/*cb*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
/*cc*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
/*cd*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
/*ce*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
/*cf*/
{
"bswap"
,
FALSE
,
LONG
,
op1
(
Ril
),
0
},
};
static
const
struct
inst
*
const
db_inst_0f
[]
=
{
db_inst_0f0x
,
db_inst_0f1x
,
db_inst_0f2x
,
db_inst_0f3x
,
db_inst_0f4x
,
db_inst_0f5x
,
db_inst_0f6x
,
db_inst_0f7x
,
db_inst_0f8x
,
db_inst_0f9x
,
db_inst_0fax
,
db_inst_0fbx
,
db_inst_0fcx
,
0
,
0
,
0
};
static
const
char
*
const
db_Esc92
[]
=
{
"fnop"
,
""
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Esc94
[]
=
{
"fchs"
,
"fabs"
,
""
,
""
,
"ftst"
,
"fxam"
,
""
,
""
};
static
const
char
*
const
db_Esc95
[]
=
{
"fld1"
,
"fldl2t"
,
"fldl2e"
,
"fldpi"
,
"fldlg2"
,
"fldln2"
,
"fldz"
,
""
};
static
const
char
*
const
db_Esc96
[]
=
{
"f2xm1"
,
"fyl2x"
,
"fptan"
,
"fpatan"
,
"fxtract"
,
"fprem1"
,
"fdecstp"
,
"fincstp"
};
static
const
char
*
const
db_Esc97
[]
=
{
"fprem"
,
"fyl2xp1"
,
"fsqrt"
,
"fsincos"
,
"frndint"
,
"fscale"
,
"fsin"
,
"fcos"
};
static
const
char
*
const
db_Esca5
[]
=
{
""
,
"fucompp"
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Escb4
[]
=
{
"fneni"
,
"fndisi"
,
"fnclex"
,
"fninit"
,
"fsetpm"
,
""
,
""
,
""
};
static
const
char
*
const
db_Esce3
[]
=
{
""
,
"fcompp"
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
char
*
const
db_Escf4
[]
=
{
"fnstsw"
,
""
,
""
,
""
,
""
,
""
,
""
,
""
};
static
const
struct
finst
db_Esc8
[]
=
{
/*0*/
{
"fadd"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*1*/
{
"fmul"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*2*/
{
"fcom"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*3*/
{
"fcomp"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*4*/
{
"fsub"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*5*/
{
"fsubr"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*6*/
{
"fdiv"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
/*7*/
{
"fdivr"
,
SNGL
,
op2
(
STI
,
ST
),
0
},
};
static
const
struct
finst
db_Esc9
[]
=
{
/*0*/
{
"fld"
,
SNGL
,
op1
(
STI
),
0
},
/*1*/
{
""
,
NONE
,
op1
(
STI
),
"fxch"
},
/*2*/
{
"fst"
,
SNGL
,
op1
(
X
),
db_Esc92
},
/*3*/
{
"fstp"
,
SNGL
,
0
,
0
},
/*4*/
{
"fldenv"
,
NONE
,
op1
(
X
),
db_Esc94
},
/*5*/
{
"fldcw"
,
NONE
,
op1
(
X
),
db_Esc95
},
/*6*/
{
"fnstenv"
,
NONE
,
op1
(
X
),
db_Esc96
},
/*7*/
{
"fnstcw"
,
NONE
,
op1
(
X
),
db_Esc97
},
};
static
const
struct
finst
db_Esca
[]
=
{
/*0*/
{
"fiadd"
,
LONG
,
0
,
0
},
/*1*/
{
"fimul"
,
LONG
,
0
,
0
},
/*2*/
{
"ficom"
,
LONG
,
0
,
0
},
/*3*/
{
"ficomp"
,
LONG
,
0
,
0
},
/*4*/
{
"fisub"
,
LONG
,
0
,
0
},
/*5*/
{
"fisubr"
,
LONG
,
op1
(
X
),
db_Esca5
},
/*6*/
{
"fidiv"
,
LONG
,
0
,
0
},
/*7*/
{
"fidivr"
,
LONG
,
0
,
0
}
};
static
const
struct
finst
db_Escb
[]
=
{
/*0*/
{
"fild"
,
LONG
,
0
,
0
},
/*1*/
{
""
,
NONE
,
0
,
0
},
/*2*/
{
"fist"
,
LONG
,
0
,
0
},
/*3*/
{
"fistp"
,
LONG
,
0
,
0
},
/*4*/
{
""
,
WORD
,
op1
(
X
),
db_Escb4
},
/*5*/
{
"fld"
,
EXTR
,
0
,
0
},
/*6*/
{
""
,
WORD
,
0
,
0
},
/*7*/
{
"fstp"
,
EXTR
,
0
,
0
},
};
static
const
struct
finst
db_Escc
[]
=
{
/*0*/
{
"fadd"
,
DBLR
,
op2
(
ST
,
STI
),
0
},
/*1*/
{
"fmul"
,
DBLR
,
op2
(
ST
,
STI
),
0
},
/*2*/
{
"fcom"
,
DBLR
,
0
,
0
},
/*3*/
{
"fcomp"
,
DBLR
,
0
,
0
},
/*4*/
{
"fsub"
,
DBLR
,
op2
(
ST
,
STI
),
"fsubr"
},
/*5*/
{
"fsubr"
,
DBLR
,
op2
(
ST
,
STI
),
"fsub"
},
/*6*/
{
"fdiv"
,
DBLR
,
op2
(
ST
,
STI
),
"fdivr"
},
/*7*/
{
"fdivr"
,
DBLR
,
op2
(
ST
,
STI
),
"fdiv"
},
};
static
const
struct
finst
db_Escd
[]
=
{
/*0*/
{
"fld"
,
DBLR
,
op1
(
STI
),
"ffree"
},
/*1*/
{
""
,
NONE
,
0
,
0
},
/*2*/
{
"fst"
,
DBLR
,
op1
(
STI
),
0
},
/*3*/
{
"fstp"
,
DBLR
,
op1
(
STI
),
0
},
/*4*/
{
"frstor"
,
NONE
,
op1
(
STI
),
"fucom"
},
/*5*/
{
""
,
NONE
,
op1
(
STI
),
"fucomp"
},
/*6*/
{
"fnsave"
,
NONE
,
0
,
0
},
/*7*/
{
"fnstsw"
,
NONE
,
0
,
0
},
};
static
const
struct
finst
db_Esce
[]
=
{
/*0*/
{
"fiadd"
,
WORD
,
op2
(
ST
,
STI
),
"faddp"
},
/*1*/
{
"fimul"
,
WORD
,
op2
(
ST
,
STI
),
"fmulp"
},
/*2*/
{
"ficom"
,
WORD
,
0
,
0
},
/*3*/
{
"ficomp"
,
WORD
,
op1
(
X
),
db_Esce3
},
/*4*/
{
"fisub"
,
WORD
,
op2
(
ST
,
STI
),
"fsubrp"
},
/*5*/
{
"fisubr"
,
WORD
,
op2
(
ST
,
STI
),
"fsubp"
},
/*6*/
{
"fidiv"
,
WORD
,
op2
(
ST
,
STI
),
"fdivrp"
},
/*7*/
{
"fidivr"
,
WORD
,
op2
(
ST
,
STI
),
"fdivp"
},
};
static
const
struct
finst
db_Escf
[]
=
{
/*0*/
{
"fild"
,
WORD
,
0
,
0
},
/*1*/
{
""
,
NONE
,
0
,
0
},
/*2*/
{
"fist"
,
WORD
,
0
,
0
},
/*3*/
{
"fistp"
,
WORD
,
0
,
0
},
/*4*/
{
"fbld"
,
NONE
,
op1
(
XA
),
db_Escf4
},
/*5*/
{
"fild"
,
QUAD
,
0
,
0
},
/*6*/
{
"fbstp"
,
NONE
,
0
,
0
},
/*7*/
{
"fistp"
,
QUAD
,
0
,
0
},
};
static
const
struct
finst
*
const
db_Esc_inst
[]
=
{
db_Esc8
,
db_Esc9
,
db_Esca
,
db_Escb
,
db_Escc
,
db_Escd
,
db_Esce
,
db_Escf
};
static
const
char
*
const
db_Grp1
[]
=
{
"add"
,
"or"
,
"adc"
,
"sbb"
,
"and"
,
"sub"
,
"xor"
,
"cmp"
};
static
const
char
*
const
db_Grp2
[]
=
{
"rol"
,
"ror"
,
"rcl"
,
"rcr"
,
"shl"
,
"shr"
,
"shl"
,
"sar"
};
static
const
struct
inst
db_Grp3
[]
=
{
{
"test"
,
TRUE
,
NONE
,
op2
(
I
,
E
),
0
},
{
"test"
,
TRUE
,
NONE
,
op2
(
I
,
E
),
0
},
{
"not"
,
TRUE
,
NONE
,
op1
(
E
),
0
},
{
"neg"
,
TRUE
,
NONE
,
op1
(
E
),
0
},
{
"mul"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
{
"imul"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
{
"div"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
{
"idiv"
,
TRUE
,
NONE
,
op2
(
E
,
A
),
0
},
};
static
const
struct
inst
db_Grp4
[]
=
{
{
"inc"
,
TRUE
,
BYTE
,
op1
(
E
),
0
},
{
"dec"
,
TRUE
,
BYTE
,
op1
(
E
),
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
}
};
static
const
struct
inst
db_Grp5
[]
=
{
{
"inc"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
{
"dec"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
{
"call"
,
TRUE
,
LONG
,
op1
(
Eind
),
0
},
{
"lcall"
,
TRUE
,
LONG
,
op1
(
Eind
),
0
},
{
"jmp"
,
TRUE
,
LONG
,
op1
(
Eind
),
0
},
{
"ljmp"
,
TRUE
,
LONG
,
op1
(
Eind
),
0
},
{
"push"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
{
""
,
TRUE
,
NONE
,
0
,
0
}
};
static
const
struct
inst
db_inst_table
[
256
]
=
{
/*00*/
{
"add"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*01*/
{
"add"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*02*/
{
"add"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*03*/
{
"add"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*04*/
{
"add"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*05*/
{
"add"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*06*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*07*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*08*/
{
"or"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*09*/
{
"or"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*0a*/
{
"or"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*0b*/
{
"or"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*0c*/
{
"or"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*0d*/
{
"or"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*0e*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*0f*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*10*/
{
"adc"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*11*/
{
"adc"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*12*/
{
"adc"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*13*/
{
"adc"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*14*/
{
"adc"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*15*/
{
"adc"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*16*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*17*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*18*/
{
"sbb"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*19*/
{
"sbb"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*1a*/
{
"sbb"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*1b*/
{
"sbb"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*1c*/
{
"sbb"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*1d*/
{
"sbb"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*1e*/
{
"push"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*1f*/
{
"pop"
,
FALSE
,
NONE
,
op1
(
Si
),
0
},
/*20*/
{
"and"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*21*/
{
"and"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*22*/
{
"and"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*23*/
{
"and"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*24*/
{
"and"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*25*/
{
"and"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*26*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*27*/
{
"daa"
,
FALSE
,
NONE
,
0
,
0
},
/*28*/
{
"sub"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*29*/
{
"sub"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*2a*/
{
"sub"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*2b*/
{
"sub"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*2c*/
{
"sub"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*2d*/
{
"sub"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*2e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*2f*/
{
"das"
,
FALSE
,
NONE
,
0
,
0
},
/*30*/
{
"xor"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*31*/
{
"xor"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*32*/
{
"xor"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*33*/
{
"xor"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*34*/
{
"xor"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*35*/
{
"xor"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*36*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*37*/
{
"aaa"
,
FALSE
,
NONE
,
0
,
0
},
/*38*/
{
"cmp"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*39*/
{
"cmp"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*3a*/
{
"cmp"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*3b*/
{
"cmp"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*3c*/
{
"cmp"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*3d*/
{
"cmp"
,
FALSE
,
LONG
,
op2
(
Is
,
A
),
0
},
/*3e*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*3f*/
{
"aas"
,
FALSE
,
NONE
,
0
,
0
},
/*40*/
{
"rex"
,
FALSE
,
NONE
,
0
,
0
},
/*41*/
{
"rex.b"
,
FALSE
,
NONE
,
0
,
0
},
/*42*/
{
"rex.x"
,
FALSE
,
NONE
,
0
,
0
},
/*43*/
{
"rex.xb"
,
FALSE
,
NONE
,
0
,
0
},
/*44*/
{
"rex.r"
,
FALSE
,
NONE
,
0
,
0
},
/*45*/
{
"rex.rb"
,
FALSE
,
NONE
,
0
,
0
},
/*46*/
{
"rex.rx"
,
FALSE
,
NONE
,
0
,
0
},
/*47*/
{
"rex.rxb"
,
FALSE
,
NONE
,
0
,
0
},
/*48*/
{
"rex.w"
,
FALSE
,
NONE
,
0
,
0
},
/*49*/
{
"rex.wb"
,
FALSE
,
NONE
,
0
,
0
},
/*4a*/
{
"rex.wx"
,
FALSE
,
NONE
,
0
,
0
},
/*4b*/
{
"rex.wxb"
,
FALSE
,
NONE
,
0
,
0
},
/*4c*/
{
"rex.wr"
,
FALSE
,
NONE
,
0
,
0
},
/*4d*/
{
"rex.wrb"
,
FALSE
,
NONE
,
0
,
0
},
/*4e*/
{
"rex.wrx"
,
FALSE
,
NONE
,
0
,
0
},
/*4f*/
{
"rex.wrxb"
,
FALSE
,
NONE
,
0
,
0
},
/*50*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*51*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*52*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*53*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*54*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*55*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*56*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*57*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*58*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*59*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5a*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5b*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5c*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5d*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5e*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*5f*/
{
"pop"
,
FALSE
,
LONG
,
op1
(
Ri
),
0
},
/*60*/
{
"pusha"
,
FALSE
,
LONG
,
0
,
0
},
/*61*/
{
"popa"
,
FALSE
,
LONG
,
0
,
0
},
/*62*/
{
"bound"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*63*/
{
"movslq"
,
TRUE
,
NONE
,
op2
(
EL
,
R
),
0
},
/*64*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*65*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*66*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*67*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*68*/
{
"push"
,
FALSE
,
LONG
,
op1
(
I
),
0
},
/*69*/
{
"imul"
,
TRUE
,
LONG
,
op3
(
I
,
E
,
R
),
0
},
/*6a*/
{
"push"
,
FALSE
,
LONG
,
op1
(
Ibs
),
0
},
/*6b*/
{
"imul"
,
TRUE
,
LONG
,
op3
(
Ibs
,
E
,
R
),
0
},
/*6c*/
{
"ins"
,
FALSE
,
BYTE
,
op2
(
DX
,
DI
),
0
},
/*6d*/
{
"ins"
,
FALSE
,
LONG
,
op2
(
DX
,
DI
),
0
},
/*6e*/
{
"outs"
,
FALSE
,
BYTE
,
op2
(
SI
,
DX
),
0
},
/*6f*/
{
"outs"
,
FALSE
,
LONG
,
op2
(
SI
,
DX
),
0
},
/*70*/
{
"jo"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*71*/
{
"jno"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*72*/
{
"jb"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*73*/
{
"jnb"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*74*/
{
"jz"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*75*/
{
"jnz"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*76*/
{
"jbe"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*77*/
{
"jnbe"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*78*/
{
"js"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*79*/
{
"jns"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7a*/
{
"jp"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7b*/
{
"jnp"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7c*/
{
"jl"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7d*/
{
"jnl"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7e*/
{
"jle"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*7f*/
{
"jnle"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*80*/
{
""
,
TRUE
,
BYTE
,
op2
(
I
,
E
),
db_Grp1
},
/*81*/
{
""
,
TRUE
,
LONG
,
op2
(
I
,
E
),
db_Grp1
},
/*82*/
{
""
,
TRUE
,
BYTE
,
op2
(
I
,
E
),
db_Grp1
},
/*83*/
{
""
,
TRUE
,
LONG
,
op2
(
Ibs
,
E
),
db_Grp1
},
/*84*/
{
"test"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*85*/
{
"test"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*86*/
{
"xchg"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*87*/
{
"xchg"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*88*/
{
"mov"
,
TRUE
,
BYTE
,
op2
(
R
,
E
),
0
},
/*89*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
R
,
E
),
0
},
/*8a*/
{
"mov"
,
TRUE
,
BYTE
,
op2
(
E
,
R
),
0
},
/*8b*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*8c*/
{
"mov"
,
TRUE
,
NONE
,
op2
(
S
,
Ew
),
0
},
/*8d*/
{
"lea"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*8e*/
{
"mov"
,
TRUE
,
NONE
,
op2
(
Ew
,
S
),
0
},
/*8f*/
{
"pop"
,
TRUE
,
LONG
,
op1
(
E
),
0
},
/*90*/
{
"nop"
,
FALSE
,
NONE
,
0
,
0
},
/*91*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*92*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*93*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*94*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*95*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*96*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*97*/
{
"xchg"
,
FALSE
,
LONG
,
op2
(
A
,
Ri
),
0
},
/*98*/
{
"cbw"
,
FALSE
,
SDEP
,
0
,
"cwde"
},
/* cbw/cwde */
/*99*/
{
"cwd"
,
FALSE
,
SDEP
,
0
,
"cdq"
},
/* cwd/cdq */
/*9a*/
{
"lcall"
,
FALSE
,
NONE
,
op1
(
OS
),
0
},
/*9b*/
{
"wait"
,
FALSE
,
NONE
,
0
,
0
},
/*9c*/
{
"pushf"
,
FALSE
,
LONG
,
0
,
0
},
/*9d*/
{
"popf"
,
FALSE
,
LONG
,
0
,
0
},
/*9e*/
{
"sahf"
,
FALSE
,
NONE
,
0
,
0
},
/*9f*/
{
"lahf"
,
FALSE
,
NONE
,
0
,
0
},
/*a0*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
O
,
A
),
0
},
/*a1*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
O
,
A
),
0
},
/*a2*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
A
,
O
),
0
},
/*a3*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
A
,
O
),
0
},
/*a4*/
{
"movs"
,
FALSE
,
BYTE
,
op2
(
SI
,
DI
),
0
},
/*a5*/
{
"movs"
,
FALSE
,
LONG
,
op2
(
SI
,
DI
),
0
},
/*a6*/
{
"cmps"
,
FALSE
,
BYTE
,
op2
(
SI
,
DI
),
0
},
/*a7*/
{
"cmps"
,
FALSE
,
LONG
,
op2
(
SI
,
DI
),
0
},
/*a8*/
{
"test"
,
FALSE
,
BYTE
,
op2
(
I
,
A
),
0
},
/*a9*/
{
"test"
,
FALSE
,
LONG
,
op2
(
I
,
A
),
0
},
/*aa*/
{
"stos"
,
FALSE
,
BYTE
,
op1
(
DI
),
0
},
/*ab*/
{
"stos"
,
FALSE
,
LONG
,
op1
(
DI
),
0
},
/*ac*/
{
"lods"
,
FALSE
,
BYTE
,
op1
(
SI
),
0
},
/*ad*/
{
"lods"
,
FALSE
,
LONG
,
op1
(
SI
),
0
},
/*ae*/
{
"scas"
,
FALSE
,
BYTE
,
op1
(
SI
),
0
},
/*af*/
{
"scas"
,
FALSE
,
LONG
,
op1
(
SI
),
0
},
/*b0*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b1*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b2*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b3*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b4*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b5*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b6*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b7*/
{
"mov"
,
FALSE
,
BYTE
,
op2
(
I
,
Ri
),
0
},
/*b8*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*b9*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*ba*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*bb*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*bc*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*bd*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*be*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*bf*/
{
"mov"
,
FALSE
,
LONG
,
op2
(
Ilq
,
Ri
),
0
},
/*c0*/
{
""
,
TRUE
,
BYTE
,
op2
(
Ib
,
E
),
db_Grp2
},
/*c1*/
{
""
,
TRUE
,
LONG
,
op2
(
Ib
,
E
),
db_Grp2
},
/*c2*/
{
"ret"
,
FALSE
,
NONE
,
op1
(
Iw
),
0
},
/*c3*/
{
"ret"
,
FALSE
,
NONE
,
0
,
0
},
/*c4*/
{
"les"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*c5*/
{
"lds"
,
TRUE
,
LONG
,
op2
(
E
,
R
),
0
},
/*c6*/
{
"mov"
,
TRUE
,
BYTE
,
op2
(
I
,
E
),
0
},
/*c7*/
{
"mov"
,
TRUE
,
LONG
,
op2
(
I
,
E
),
0
},
/*c8*/
{
"enter"
,
FALSE
,
NONE
,
op2
(
Iw
,
Ib
),
0
},
/*c9*/
{
"leave"
,
FALSE
,
NONE
,
0
,
0
},
/*ca*/
{
"lret"
,
FALSE
,
NONE
,
op1
(
Iw
),
0
},
/*cb*/
{
"lret"
,
FALSE
,
NONE
,
0
,
0
},
/*cc*/
{
"int"
,
FALSE
,
NONE
,
op1
(
o3
),
0
},
/*cd*/
{
"int"
,
FALSE
,
NONE
,
op1
(
Ib
),
0
},
/*ce*/
{
"into"
,
FALSE
,
NONE
,
0
,
0
},
/*cf*/
{
"iret"
,
FALSE
,
NONE
,
0
,
0
},
/*d0*/
{
""
,
TRUE
,
BYTE
,
op2
(
o1
,
E
),
db_Grp2
},
/*d1*/
{
""
,
TRUE
,
LONG
,
op2
(
o1
,
E
),
db_Grp2
},
/*d2*/
{
""
,
TRUE
,
BYTE
,
op2
(
CL
,
E
),
db_Grp2
},
/*d3*/
{
""
,
TRUE
,
LONG
,
op2
(
CL
,
E
),
db_Grp2
},
/*d4*/
{
"aam"
,
FALSE
,
NONE
,
op1
(
Iba
),
0
},
/*d5*/
{
"aad"
,
FALSE
,
NONE
,
op1
(
Iba
),
0
},
/*d6*/
{
".byte
\t
0xd6"
,
FALSE
,
NONE
,
0
,
0
},
/*d7*/
{
"xlat"
,
FALSE
,
BYTE
,
op1
(
BX
),
0
},
/*d8*/
{
""
,
TRUE
,
NONE
,
0
,
db_Esc8
},
/*d9*/
{
""
,
TRUE
,
NONE
,
0
,
db_Esc9
},
/*da*/
{
""
,
TRUE
,
NONE
,
0
,
db_Esca
},
/*db*/
{
""
,
TRUE
,
NONE
,
0
,
db_Escb
},
/*dc*/
{
""
,
TRUE
,
NONE
,
0
,
db_Escc
},
/*dd*/
{
""
,
TRUE
,
NONE
,
0
,
db_Escd
},
/*de*/
{
""
,
TRUE
,
NONE
,
0
,
db_Esce
},
/*df*/
{
""
,
TRUE
,
NONE
,
0
,
db_Escf
},
/*e0*/
{
"loopne"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*e1*/
{
"loope"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*e2*/
{
"loop"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*e3*/
{
"jcxz"
,
FALSE
,
SDEP
,
op1
(
Db
),
"jecxz"
},
/*e4*/
{
"in"
,
FALSE
,
BYTE
,
op2
(
Ib
,
A
),
0
},
/*e5*/
{
"in"
,
FALSE
,
LONG
,
op2
(
Ib
,
A
)
,
0
},
/*e6*/
{
"out"
,
FALSE
,
BYTE
,
op2
(
A
,
Ib
),
0
},
/*e7*/
{
"out"
,
FALSE
,
LONG
,
op2
(
A
,
Ib
)
,
0
},
/*e8*/
{
"call"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*e9*/
{
"jmp"
,
FALSE
,
NONE
,
op1
(
Dl
),
0
},
/*ea*/
{
"ljmp"
,
FALSE
,
NONE
,
op1
(
OS
),
0
},
/*eb*/
{
"jmp"
,
FALSE
,
NONE
,
op1
(
Db
),
0
},
/*ec*/
{
"in"
,
FALSE
,
BYTE
,
op2
(
DX
,
A
),
0
},
/*ed*/
{
"in"
,
FALSE
,
LONG
,
op2
(
DX
,
A
)
,
0
},
/*ee*/
{
"out"
,
FALSE
,
BYTE
,
op2
(
A
,
DX
),
0
},
/*ef*/
{
"out"
,
FALSE
,
LONG
,
op2
(
A
,
DX
)
,
0
},
/*f0*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*f1*/
{
".byte
\t
0xf1"
,
FALSE
,
NONE
,
0
,
0
},
/*f2*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*f3*/
{
""
,
FALSE
,
NONE
,
0
,
0
},
/*f4*/
{
"hlt"
,
FALSE
,
NONE
,
0
,
0
},
/*f5*/
{
"cmc"
,
FALSE
,
NONE
,
0
,
0
},
/*f6*/
{
""
,
TRUE
,
BYTE
,
0
,
db_Grp3
},
/*f7*/
{
""
,
TRUE
,
LONG
,
0
,
db_Grp3
},
/*f8*/
{
"clc"
,
FALSE
,
NONE
,
0
,
0
},
/*f9*/
{
"stc"
,
FALSE
,
NONE
,
0
,
0
},
/*fa*/
{
"cli"
,
FALSE
,
NONE
,
0
,
0
},
/*fb*/
{
"sti"
,
FALSE
,
NONE
,
0
,
0
},
/*fc*/
{
"cld"
,
FALSE
,
NONE
,
0
,
0
},
/*fd*/
{
"std"
,
FALSE
,
NONE
,
0
,
0
},
/*fe*/
{
""
,
TRUE
,
NONE
,
0
,
db_Grp4
},
/*ff*/
{
""
,
TRUE
,
NONE
,
0
,
db_Grp5
},
};
static
const
struct
inst
db_bad_inst
=
{
"???"
,
FALSE
,
NONE
,
0
,
0
}
;
#define f_mod(rex, byte) ((byte)>>6)
#define f_reg(rex, byte) ((((byte)>>3)&0x7) | (rex & REX_R ? 0x8 : 0x0))
#define f_rm(rex, byte) (((byte)&0x7) | (rex & REX_B ? 0x8 : 0x0))
#define sib_ss(rex, byte) ((byte)>>6)
#define sib_index(rex, byte) ((((byte)>>3)&0x7) | (rex & REX_X ? 0x8 : 0x0))
#define sib_base(rex, byte) (((byte)&0x7) | (rex & REX_B ? 0x8 : 0x0))
struct
i_addr
{
int
is_reg
;
/* if reg, reg number is in 'disp' */
int
disp
;
const
char
*
base
;
const
char
*
index
;
int
ss
;
};
static
const
char
*
const
db_reg
[
2
][
4
][
16
]
=
{
{{
"%al"
,
"%cl"
,
"%dl"
,
"%bl"
,
"%ah"
,
"%ch"
,
"%dh"
,
"%bh"
,
"%r8b"
,
"%r9b"
,
"%r10b"
,
"%r11b"
,
"%r12b"
,
"%r13b"
,
"%r14b"
,
"%r15b"
},
{
"%ax"
,
"%cx"
,
"%dx"
,
"%bx"
,
"%sp"
,
"%bp"
,
"%si"
,
"%di"
,
"%r8w"
,
"%r9w"
,
"%r10w"
,
"%r11w"
,
"%r12w"
,
"%r13w"
,
"%r14w"
,
"%r15w"
},
{
"%eax"
,
"%ecx"
,
"%edx"
,
"%ebx"
,
"%esp"
,
"%ebp"
,
"%esi"
,
"%edi"
,
"%r8d"
,
"%r9d"
,
"%r10d"
,
"%r11d"
,
"%r12d"
,
"%r13d"
,
"%r14d"
,
"%r15d"
},
{
"%rax"
,
"%rcx"
,
"%rdx"
,
"%rbx"
,
"%rsp"
,
"%rbp"
,
"%rsi"
,
"%rdi"
,
"%r8"
,
"%r9"
,
"%r10"
,
"%r11"
,
"%r12"
,
"%r13"
,
"%r14"
,
"%r15"
}},
{{
"%al"
,
"%cl"
,
"%dl"
,
"%bl"
,
"%spl"
,
"%bpl"
,
"%sil"
,
"%dil"
,
"%r8b"
,
"%r9b"
,
"%r10b"
,
"%r11b"
,
"%r12b"
,
"%r13b"
,
"%r14b"
,
"%r15b"
},
{
"%ax"
,
"%cx"
,
"%dx"
,
"%bx"
,
"%sp"
,
"%bp"
,
"%si"
,
"%di"
,
"%r8w"
,
"%r9w"
,
"%r10w"
,
"%r11w"
,
"%r12w"
,
"%r13w"
,
"%r14w"
,
"%r15w"
},
{
"%eax"
,
"%ecx"
,
"%edx"
,
"%ebx"
,
"%esp"
,
"%ebp"
,
"%esi"
,
"%edi"
,
"%r8d"
,
"%r9d"
,
"%r10d"
,
"%r11d"
,
"%r12d"
,
"%r13d"
,
"%r14d"
,
"%r15d"
},
{
"%rax"
,
"%rcx"
,
"%rdx"
,
"%rbx"
,
"%rsp"
,
"%rbp"
,
"%rsi"
,
"%rdi"
,
"%r8"
,
"%r9"
,
"%r10"
,
"%r11"
,
"%r12"
,
"%r13"
,
"%r14"
,
"%r15"
}}
};
static
const
char
*
const
db_seg_reg
[
8
]
=
{
"%es"
,
"%cs"
,
"%ss"
,
"%ds"
,
"%fs"
,
"%gs"
,
""
,
""
};
/*
* lengths for size attributes
*/
static
const
int
db_lengths
[]
=
{
1
,
/* BYTE */
2
,
/* WORD */
4
,
/* LONG */
8
,
/* QUAD */
4
,
/* SNGL */
8
,
/* DBLR */
10
,
/* EXTR */
};
#define get_value_inc(result, loc, size, is_signed) \
result = db_get_value((loc), (size), (is_signed)); \
(loc) += (size);
static
db_addr_t
db_disasm_esc
(
db_addr_t
loc
,
int
inst
,
int
rex
,
int
short_addr
,
int
size
,
const
char
*
seg
);
static
void
db_print_address
(
const
char
*
seg
,
int
size
,
int
rex
,
struct
i_addr
*
addrp
);
static
db_addr_t
db_read_address
(
db_addr_t
loc
,
int
short_addr
,
int
rex
,
int
regmodrm
,
struct
i_addr
*
addrp
);
/*
* Read address at location and return updated location.
*/
static
db_addr_t
db_read_address
(
loc
,
short_addr
,
rex
,
regmodrm
,
addrp
)
db_addr_t
loc
;
int
short_addr
;
int
rex
;
int
regmodrm
;
struct
i_addr
*
addrp
;
/* out */
{
int
mod
,
rm
,
sib
,
index
,
disp
,
size
,
have_sib
;
mod
=
f_mod
(
rex
,
regmodrm
);
rm
=
f_rm
(
rex
,
regmodrm
);
if
(
mod
==
3
)
{
addrp
->
is_reg
=
TRUE
;
addrp
->
disp
=
rm
;
return
(
loc
);
}
addrp
->
is_reg
=
FALSE
;
addrp
->
index
=
0
;
if
(
short_addr
)
size
=
LONG
;
else
size
=
QUAD
;
if
((
rm
&
0x7
)
==
4
)
{
get_value_inc
(
sib
,
loc
,
1
,
FALSE
);
rm
=
sib_base
(
rex
,
sib
);
index
=
sib_index
(
rex
,
sib
);
if
(
index
!=
4
)
addrp
->
index
=
db_reg
[
1
][
size
][
index
];
addrp
->
ss
=
sib_ss
(
rex
,
sib
);
have_sib
=
1
;
}
else
have_sib
=
0
;
switch
(
mod
)
{
case
0
:
if
(
rm
==
5
)
{
get_value_inc
(
addrp
->
disp
,
loc
,
4
,
FALSE
);
if
(
have_sib
)
addrp
->
base
=
0
;
else
if
(
short_addr
)
addrp
->
base
=
"%eip"
;
else
addrp
->
base
=
"%rip"
;
}
else
{
addrp
->
disp
=
0
;
addrp
->
base
=
db_reg
[
1
][
size
][
rm
];
}
break
;
case
1
:
get_value_inc
(
disp
,
loc
,
1
,
TRUE
);
addrp
->
disp
=
disp
;
addrp
->
base
=
db_reg
[
1
][
size
][
rm
];
break
;
case
2
:
get_value_inc
(
disp
,
loc
,
4
,
FALSE
);
addrp
->
disp
=
disp
;
addrp
->
base
=
db_reg
[
1
][
size
][
rm
];
break
;
}
return
(
loc
);
}
static
void
db_print_address
(
seg
,
size
,
rex
,
addrp
)
const
char
*
seg
;
int
size
;
int
rex
;
struct
i_addr
*
addrp
;
{
if
(
addrp
->
is_reg
)
{
db_printf
(
"%s"
,
db_reg
[
rex
!=
0
?
1
:
0
][(
size
==
LONG
&&
(
rex
&
REX_W
))
?
QUAD
:
size
][
addrp
->
disp
]);
return
;
}
if
(
seg
)
{
db_printf
(
"%s:"
,
seg
);
}
if
(
addrp
->
disp
!=
0
||
(
addrp
->
base
==
0
&&
addrp
->
index
==
0
))
db_printsym
((
db_addr_t
)
addrp
->
disp
,
DB_STGY_ANY
);
if
(
addrp
->
base
!=
0
||
addrp
->
index
!=
0
)
{
db_printf
(
"("
);
if
(
addrp
->
base
)
db_printf
(
"%s"
,
addrp
->
base
);
if
(
addrp
->
index
)
db_printf
(
",%s,%d"
,
addrp
->
index
,
1
<<
addrp
->
ss
);
db_printf
(
")"
);
}
}
/*
* Disassemble floating-point ("escape") instruction
* and return updated location.
*/
static
db_addr_t
db_disasm_esc
(
loc
,
inst
,
rex
,
short_addr
,
size
,
seg
)
db_addr_t
loc
;
int
inst
;
int
rex
;
int
short_addr
;
int
size
;
const
char
*
seg
;
{
int
regmodrm
;
const
struct
finst
*
fp
;
int
mod
;
struct
i_addr
address
;
const
char
*
name
;
get_value_inc
(
regmodrm
,
loc
,
1
,
FALSE
);
fp
=
&
db_Esc_inst
[
inst
-
0xd8
][
f_reg
(
rex
,
regmodrm
)];
mod
=
f_mod
(
rex
,
regmodrm
);
if
(
mod
!=
3
)
{
if
(
*
fp
->
f_name
==
'\0'
)
{
db_printf
(
"<bad instruction>"
);
return
(
loc
);
}
/*
* Normal address modes.
*/
loc
=
db_read_address
(
loc
,
short_addr
,
rex
,
regmodrm
,
&
address
);
db_printf
(
"%s"
,
fp
->
f_name
);
switch
(
fp
->
f_size
)
{
case
SNGL
:
db_printf
(
"s"
);
break
;
case
DBLR
:
db_printf
(
"l"
);
break
;
case
EXTR
:
db_printf
(
"t"
);
break
;
case
WORD
:
db_printf
(
"s"
);
break
;
case
LONG
:
db_printf
(
"l"
);
break
;
case
QUAD
:
db_printf
(
"q"
);
break
;
default
:
break
;
}
db_printf
(
"
\t
"
);
db_print_address
(
seg
,
BYTE
,
rex
,
&
address
);
}
else
{
/*
* 'reg-reg' - special formats
*/
switch
(
fp
->
f_rrmode
)
{
case
op2
(
ST
,
STI
):
name
=
(
fp
->
f_rrname
)
?
fp
->
f_rrname
:
fp
->
f_name
;
db_printf
(
"%s
\t
%%st,%%st(%d)"
,
name
,
f_rm
(
rex
,
regmodrm
));
break
;
case
op2
(
STI
,
ST
):
name
=
(
fp
->
f_rrname
)
?
fp
->
f_rrname
:
fp
->
f_name
;
db_printf
(
"%s
\t
%%st(%d),%%st"
,
name
,
f_rm
(
rex
,
regmodrm
));
break
;
case
op1
(
STI
):
name
=
(
fp
->
f_rrname
)
?
fp
->
f_rrname
:
fp
->
f_name
;
db_printf
(
"%s
\t
%%st(%d)"
,
name
,
f_rm
(
rex
,
regmodrm
));
break
;
case
op1
(
X
):
name
=
((
const
char
*
const
*
)
fp
->
f_rrname
)[
f_rm
(
rex
,
regmodrm
)];
if
(
*
name
==
'\0'
)
goto
bad
;
db_printf
(
"%s"
,
name
);
break
;
case
op1
(
XA
):
name
=
((
const
char
*
const
*
)
fp
->
f_rrname
)[
f_rm
(
rex
,
regmodrm
)];
if
(
*
name
==
'\0'
)
goto
bad
;
db_printf
(
"%s
\t
%%ax"
,
name
);
break
;
default
:
bad
:
db_printf
(
"<bad instruction>"
);
break
;
}
}
return
(
loc
);
}
/*
* Disassemble instruction at 'loc'. 'altfmt' specifies an
* (optional) alternate format. Return address of start of
* next instruction.
*/
static
db_addr_t
db_disasm
(
db_addr_t
loc
,
boolean_t
altfmt
)
{
int
inst
;
int
size
;
int
short_addr
;
const
char
*
seg
;
const
struct
inst
*
ip
;
const
char
*
i_name
;
int
i_size
;
int
i_mode
;
int
rex
=
0
;
int
regmodrm
=
0
;
boolean_t
first
;
int
displ
;
int
prefix
;
int
rep
;
int
imm
;
int
imm2
;
LONG64
imm64
;
int
len
;
struct
i_addr
address
;
db_addr_t
addr
;
get_value_inc
(
inst
,
loc
,
1
,
FALSE
);
short_addr
=
FALSE
;
size
=
LONG
;
seg
=
0
;
/*
* Get prefixes
*/
rep
=
FALSE
;
prefix
=
TRUE
;
do
{
switch
(
inst
)
{
case
0x66
:
/* data16 */
size
=
WORD
;
break
;
case
0x67
:
short_addr
=
TRUE
;
break
;
case
0x26
:
seg
=
"%es"
;
break
;
case
0x36
:
seg
=
"%ss"
;
break
;
case
0x2e
:
seg
=
"%cs"
;
break
;
case
0x3e
:
seg
=
"%ds"
;
break
;
case
0x64
:
seg
=
"%fs"
;
break
;
case
0x65
:
seg
=
"%gs"
;
break
;
case
0xf0
:
db_printf
(
"lock "
);
break
;
case
0xf2
:
db_printf
(
"repne "
);
break
;
case
0xf3
:
rep
=
TRUE
;
break
;
default
:
prefix
=
FALSE
;
break
;
}
if
(
inst
>=
0x40
&&
inst
<
0x50
)
{
rex
=
inst
;
prefix
=
TRUE
;
}
if
(
prefix
)
{
get_value_inc
(
inst
,
loc
,
1
,
FALSE
);
}
if
(
rep
==
TRUE
)
{
if
(
inst
==
0x90
)
{
db_printf
(
"pause
\n
"
);
return
(
loc
);
}
db_printf
(
"repe "
);
/* XXX repe VS rep */
rep
=
FALSE
;
}
}
while
(
prefix
);
if
(
inst
>=
0xd8
&&
inst
<=
0xdf
)
{
loc
=
db_disasm_esc
(
loc
,
inst
,
rex
,
short_addr
,
size
,
seg
);
db_printf
(
"
\n
"
);
return
(
loc
);
}
if
(
inst
==
0x0f
)
{
get_value_inc
(
inst
,
loc
,
1
,
FALSE
);
ip
=
db_inst_0f
[
inst
>>
4
];
if
(
ip
==
0
)
{
ip
=
&
db_bad_inst
;
}
else
{
ip
=
&
ip
[
inst
&
0xf
];
}
}
else
ip
=
&
db_inst_table
[
inst
];
if
(
ip
->
i_has_modrm
)
{
get_value_inc
(
regmodrm
,
loc
,
1
,
FALSE
);
loc
=
db_read_address
(
loc
,
short_addr
,
rex
,
regmodrm
,
&
address
);
}
i_name
=
ip
->
i_name
;
i_size
=
ip
->
i_size
;
i_mode
=
ip
->
i_mode
;
if
(
ip
->
i_extra
==
db_Grp1
||
ip
->
i_extra
==
db_Grp2
||
ip
->
i_extra
==
db_Grp6
||
ip
->
i_extra
==
db_Grp7
||
ip
->
i_extra
==
db_Grp8
||
ip
->
i_extra
==
db_Grp9
||
ip
->
i_extra
==
db_Grp15
)
{
i_name
=
((
const
char
*
const
*
)
ip
->
i_extra
)[
f_reg
(
rex
,
regmodrm
)];
}
else
if
(
ip
->
i_extra
==
db_Grp3
)
{
ip
=
ip
->
i_extra
;
ip
=
&
ip
[
f_reg
(
rex
,
regmodrm
)];
i_name
=
ip
->
i_name
;
i_mode
=
ip
->
i_mode
;
}
else
if
(
ip
->
i_extra
==
db_Grp4
||
ip
->
i_extra
==
db_Grp5
)
{
ip
=
ip
->
i_extra
;
ip
=
&
ip
[
f_reg
(
rex
,
regmodrm
)];
i_name
=
ip
->
i_name
;
i_mode
=
ip
->
i_mode
;
i_size
=
ip
->
i_size
;
}
/* Special cases that don't fit well in the tables. */
if
(
ip
->
i_extra
==
db_Grp7
&&
f_mod
(
rex
,
regmodrm
)
==
3
)
{
switch
(
regmodrm
)
{
case
0xc8
:
i_name
=
"monitor"
;
i_size
=
NONE
;
i_mode
=
0
;
break
;
case
0xc9
:
i_name
=
"mwait"
;
i_size
=
NONE
;
i_mode
=
0
;
break
;
case
0xf8
:
i_name
=
"swapgs"
;
i_size
=
NONE
;
i_mode
=
0
;
break
;
}
}
if
(
ip
->
i_extra
==
db_Grp15
&&
f_mod
(
0
,
regmodrm
)
==
3
)
{
i_name
=
db_Grp15b
[
f_reg
(
0
,
regmodrm
)];
i_size
=
NONE
;
i_mode
=
0
;
}
if
(
i_size
==
SDEP
)
{
if
(
size
==
WORD
)
db_printf
(
"%s"
,
i_name
);
else
db_printf
(
"%s"
,
(
const
char
*
)
ip
->
i_extra
);
}
else
{
db_printf
(
"%s"
,
i_name
);
if
((
inst
>=
0x50
&&
inst
<=
0x5f
)
||
inst
==
0x68
||
inst
==
0x6a
)
{
i_size
=
NONE
;
db_printf
(
"q"
);
}
if
(
i_size
!=
NONE
)
{
if
(
i_size
==
BYTE
)
{
db_printf
(
"b"
);
size
=
BYTE
;
}
else
if
(
i_size
==
WORD
)
{
db_printf
(
"w"
);
size
=
WORD
;
}
else
if
(
size
==
WORD
)
db_printf
(
"w"
);
else
{
if
(
rex
&
REX_W
)
db_printf
(
"q"
);
else
db_printf
(
"l"
);
}
}
}
db_printf
(
"
\t
"
);
for
(
first
=
TRUE
;
i_mode
!=
0
;
i_mode
>>=
8
,
first
=
FALSE
)
{
if
(
!
first
)
db_printf
(
","
);
switch
(
i_mode
&
0xFF
)
{
case
E
:
db_print_address
(
seg
,
size
,
rex
,
&
address
);
break
;
case
Eind
:
db_printf
(
"*"
);
db_print_address
(
seg
,
size
,
rex
,
&
address
);
break
;
case
El
:
db_print_address
(
seg
,
(
rex
&
REX_W
)
?
QUAD
:
LONG
,
rex
,
&
address
);
break
;
case
EL
:
db_print_address
(
seg
,
LONG
,
0
,
&
address
);
break
;
case
Ew
:
db_print_address
(
seg
,
WORD
,
rex
,
&
address
);
break
;
case
Eb
:
db_print_address
(
seg
,
BYTE
,
rex
,
&
address
);
break
;
case
R
:
db_printf
(
"%s"
,
db_reg
[
rex
!=
0
?
1
:
0
][(
size
==
LONG
&&
(
rex
&
REX_W
))
?
QUAD
:
size
][
f_reg
(
rex
,
regmodrm
)]);
break
;
case
Rw
:
db_printf
(
"%s"
,
db_reg
[
rex
!=
0
?
1
:
0
][
WORD
][
f_reg
(
rex
,
regmodrm
)]);
break
;
case
Ri
:
db_printf
(
"%s"
,
db_reg
[
0
][
QUAD
][
f_rm
(
rex
,
inst
)]);
break
;
case
Ril
:
db_printf
(
"%s"
,
db_reg
[
rex
!=
0
?
1
:
0
][(
rex
&
REX_R
)
?
QUAD
:
LONG
][
f_rm
(
rex
,
inst
)]);
break
;
case
S
:
db_printf
(
"%s"
,
db_seg_reg
[
f_reg
(
0
,
regmodrm
)]);
break
;
case
Si
:
db_printf
(
"%s"
,
db_seg_reg
[
f_reg
(
0
,
inst
)]);
break
;
case
A
:
db_printf
(
"%s"
,
db_reg
[
rex
!=
0
?
1
:
0
][
size
][
0
]);
/* acc */
break
;
case
BX
:
if
(
seg
)
db_printf
(
"%s:"
,
seg
);
db_printf
(
"(%s)"
,
short_addr
?
"%bx"
:
"%ebx"
);
break
;
case
CL
:
db_printf
(
"%%cl"
);
break
;
case
DX
:
db_printf
(
"%%dx"
);
break
;
case
SI
:
if
(
seg
)
db_printf
(
"%s:"
,
seg
);
db_printf
(
"(%s)"
,
short_addr
?
"%si"
:
"%rsi"
);
break
;
case
DI
:
db_printf
(
"%%es:(%s)"
,
short_addr
?
"%di"
:
"%rdi"
);
break
;
case
CR
:
db_printf
(
"%%cr%d"
,
f_reg
(
rex
,
regmodrm
));
break
;
case
DR
:
db_printf
(
"%%dr%d"
,
f_reg
(
rex
,
regmodrm
));
break
;
case
TR
:
db_printf
(
"%%tr%d"
,
f_reg
(
rex
,
regmodrm
));
break
;
case
I
:
len
=
db_lengths
[
size
];
get_value_inc
(
imm
,
loc
,
len
,
FALSE
);
db_printf
(
"$%#x"
,
imm
);
break
;
case
Is
:
len
=
db_lengths
[(
size
==
LONG
&&
(
rex
&
REX_W
))
?
QUAD
:
size
];
get_value_inc
(
imm
,
loc
,
len
,
FALSE
);
db_printf
(
"$%x"
,
imm
);
break
;
case
Ib
:
get_value_inc
(
imm
,
loc
,
1
,
FALSE
);
db_printf
(
"$%#x"
,
imm
);
break
;
case
Iba
:
get_value_inc
(
imm
,
loc
,
1
,
FALSE
);
if
(
imm
!=
0x0a
)
db_printf
(
"$%#x"
,
imm
);
break
;
case
Ibs
:
get_value_inc
(
imm
,
loc
,
1
,
TRUE
);
if
(
size
==
WORD
)
imm
&=
0xFFFF
;
db_printf
(
"$%x"
,
imm
);
break
;
case
Iw
:
get_value_inc
(
imm
,
loc
,
2
,
FALSE
);
db_printf
(
"$%#x"
,
imm
);
break
;
case
Ilq
:
len
=
db_lengths
[
rex
&
REX_W
?
QUAD
:
LONG
];
get_value_inc
(
imm64
,
loc
,
len
,
FALSE
);
db_printf
(
"$%#I64x"
,
imm64
);
break
;
case
O
:
len
=
(
short_addr
?
2
:
4
);
get_value_inc
(
displ
,
loc
,
len
,
FALSE
);
if
(
seg
)
db_printf
(
"%s:%x"
,
seg
,
displ
);
else
db_printsym
((
db_addr_t
)
displ
,
DB_STGY_ANY
);
break
;
case
Db
:
get_value_inc
(
displ
,
loc
,
1
,
TRUE
);
addr
=
loc
+
(
LONG64
)
displ
;
if
(
size
==
WORD
)
addr
&=
0xFFFF
;
db_printsym
(
addr
,
DB_STGY_XTRN
);
break
;
case
Dl
:
len
=
db_lengths
[(
size
==
LONG
&&
(
rex
&
REX_W
))
?
QUAD
:
size
];
get_value_inc
(
displ
,
loc
,
len
,
FALSE
);
addr
=
loc
+
(
LONG64
)
displ
;
if
(
size
==
WORD
)
addr
&=
0xFFFF
;
db_printsym
(
addr
,
DB_STGY_XTRN
);
break
;
case
o1
:
db_printf
(
"$1"
);
break
;
case
o3
:
db_printf
(
"$3"
);
break
;
case
OS
:
len
=
db_lengths
[
size
];
get_value_inc
(
imm
,
loc
,
len
,
FALSE
);
/* offset */
get_value_inc
(
imm2
,
loc
,
2
,
FALSE
);
/* segment */
db_printf
(
"$%#x,%#x"
,
imm2
,
imm
);
break
;
case
MX
:
db_printf
(
"%%mm%d"
,
f_reg
(
rex
,
regmodrm
));
break
;
case
EMX
:
db_printf
(
"%%mm%d"
,
f_rm
(
rex
,
regmodrm
));
break
;
case
XMM
:
db_printf
(
"%%xmm%d"
,
f_reg
(
rex
,
regmodrm
));
break
;
case
EXMM
:
db_printf
(
"%%xmm%d"
,
f_rm
(
rex
,
regmodrm
));
break
;
}
}
return
(
loc
);
}
void
be_x86_64_disasm_one_insn
(
ADDRESS64
*
addr
,
int
display
)
{
db_printf
=
display
?
dbg_printf
:
no_printf
;
addr
->
Offset
=
db_disasm
(
addr
->
Offset
,
TRUE
);
}
programs/winedbg/debugger.h
View file @
1774db38
...
...
@@ -416,6 +416,7 @@ extern BOOL memory_get_string(struct dbg_process* pcs, void* addr, B
extern
BOOL
memory_get_string_indirect
(
struct
dbg_process
*
pcs
,
void
*
addr
,
BOOL
unicode
,
WCHAR
*
buffer
,
int
size
);
extern
BOOL
memory_get_register
(
DWORD
regno
,
struct
dbg_lvalue
*
value
,
char
*
buffer
,
int
len
);
extern
void
memory_disassemble
(
const
struct
dbg_lvalue
*
,
const
struct
dbg_lvalue
*
,
int
instruction_count
);
extern
void
memory_disasm_one_x86_insn
(
ADDRESS64
*
addr
,
int
display
);
extern
BOOL
memory_disasm_one_insn
(
ADDRESS64
*
addr
);
#define MAX_OFFSET_TO_STR_LEN 19
extern
char
*
memory_offset_to_string
(
char
*
str
,
DWORD64
offset
,
unsigned
mode
);
...
...
programs/winedbg/memory.c
View file @
1774db38
...
...
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <Zydis/Zydis.h>
#include "debugger.h"
#include "wine/debug.h"
...
...
@@ -696,12 +697,7 @@ void print_bare_address(const ADDRESS64* addr)
}
}
/***********************************************************************
* print_address
*
* Print an 16- or 32-bit address, with the nearest symbol if any.
*/
void
print_address
(
const
ADDRESS64
*
addr
,
BOOLEAN
with_line
)
static
void
print_address_symbol
(
const
ADDRESS64
*
addr
,
BOOL
with_line
,
const
char
*
sep
)
{
char
buffer
[
sizeof
(
SYMBOL_INFO
)
+
256
];
SYMBOL_INFO
*
si
=
(
SYMBOL_INFO
*
)
buffer
;
...
...
@@ -710,21 +706,19 @@ void print_address(const ADDRESS64* addr, BOOLEAN with_line)
DWORD
disp
;
IMAGEHLP_MODULE
im
;
print_bare_address
(
addr
);
si
->
SizeOfStruct
=
sizeof
(
*
si
);
si
->
MaxNameLen
=
256
;
im
.
SizeOfStruct
=
0
;
if
(
SymFromAddr
(
dbg_curr_process
->
handle
,
lin
,
&
disp64
,
si
)
&&
disp64
<
si
->
Size
)
{
dbg_printf
(
"
%s"
,
si
->
Name
);
dbg_printf
(
"
%s %s"
,
sep
,
si
->
Name
);
if
(
disp64
)
dbg_printf
(
"+0x%I64x"
,
disp64
);
}
else
{
im
.
SizeOfStruct
=
sizeof
(
im
);
if
(
!
SymGetModuleInfo
(
dbg_curr_process
->
handle
,
lin
,
&
im
))
return
;
dbg_printf
(
"
%s"
,
im
.
ModuleName
);
dbg_printf
(
"
%s %s"
,
sep
,
im
.
ModuleName
);
if
(
lin
>
im
.
BaseOfImage
)
dbg_printf
(
"+0x%Ix"
,
lin
-
(
DWORD_PTR
)
im
.
BaseOfImage
);
}
...
...
@@ -744,6 +738,89 @@ void print_address(const ADDRESS64* addr, BOOLEAN with_line)
}
}
/***********************************************************************
* print_address
*
* Print an 16- or 32-bit address, with the nearest symbol if any.
*/
void
print_address
(
const
ADDRESS64
*
addr
,
BOOLEAN
with_line
)
{
print_bare_address
(
addr
);
print_address_symbol
(
addr
,
with_line
,
""
);
}
void
memory_disasm_one_x86_insn
(
ADDRESS64
*
addr
,
int
display
)
{
ZydisDisassembledInstruction
instr
=
{
.
runtime_address
=
addr
->
Offset
};
ZydisDecoder
decoder
;
ZydisDecoderContext
ctx
;
unsigned
char
buffer
[
16
];
SIZE_T
len
;
int
i
;
if
(
!
dbg_curr_process
->
process_io
->
read
(
dbg_curr_process
->
handle
,
memory_to_linear_addr
(
addr
),
buffer
,
sizeof
(
buffer
),
&
len
))
return
;
switch
(
addr
->
Mode
)
{
case
AddrModeReal
:
case
AddrMode1616
:
ZydisDecoderInit
(
&
decoder
,
ZYDIS_MACHINE_MODE_LEGACY_16
,
ZYDIS_STACK_WIDTH_16
);
break
;
default:
if
(
ADDRSIZE
==
4
)
ZydisDecoderInit
(
&
decoder
,
ZYDIS_MACHINE_MODE_LEGACY_32
,
ZYDIS_STACK_WIDTH_32
);
else
ZydisDecoderInit
(
&
decoder
,
ZYDIS_MACHINE_MODE_LONG_64
,
ZYDIS_STACK_WIDTH_64
);
break
;
}
ZydisDecoderDecodeInstruction
(
&
decoder
,
&
ctx
,
buffer
,
len
,
&
instr
.
info
);
ZydisDecoderDecodeOperands
(
&
decoder
,
&
ctx
,
&
instr
.
info
,
instr
.
operands
,
instr
.
info
.
operand_count
);
if
(
display
)
{
ZydisFormatter
formatter
;
ZydisFormatterInit
(
&
formatter
,
ZYDIS_FORMATTER_STYLE_ATT
);
ZydisFormatterSetProperty
(
&
formatter
,
ZYDIS_FORMATTER_PROP_HEX_UPPERCASE
,
0
);
ZydisFormatterFormatInstruction
(
&
formatter
,
&
instr
.
info
,
instr
.
operands
,
instr
.
info
.
operand_count_visible
,
instr
.
text
,
sizeof
(
instr
.
text
),
instr
.
runtime_address
,
NULL
);
dbg_printf
(
"%s"
,
instr
.
text
);
for
(
i
=
0
;
i
<
instr
.
info
.
operand_count_visible
;
i
++
)
{
ADDRESS64
a
=
{
.
Mode
=
AddrModeFlat
};
ZyanU64
addr
;
if
(
!
ZYAN_SUCCESS
(
ZydisCalcAbsoluteAddress
(
&
instr
.
info
,
&
instr
.
operands
[
i
],
instr
.
runtime_address
,
&
addr
)))
continue
;
if
(
instr
.
info
.
meta
.
branch_type
==
ZYDIS_BRANCH_TYPE_NEAR
&&
instr
.
operands
[
i
].
type
==
ZYDIS_OPERAND_TYPE_MEMORY
&&
instr
.
operands
[
i
].
mem
.
disp
.
has_displacement
&&
instr
.
operands
[
i
].
mem
.
index
==
ZYDIS_REGISTER_NONE
&&
(
instr
.
operands
[
i
].
mem
.
base
==
ZYDIS_REGISTER_NONE
||
instr
.
operands
[
i
].
mem
.
base
==
ZYDIS_REGISTER_EIP
||
instr
.
operands
[
i
].
mem
.
base
==
ZYDIS_REGISTER_RIP
))
{
unsigned
char
dest
[
8
];
if
(
dbg_read_memory
(
(
void
*
)(
ULONG_PTR
)
addr
,
dest
,
ADDRSIZE
))
{
dbg_printf
(
" -> "
);
a
.
Offset
=
ADDRSIZE
==
4
?
*
(
DWORD
*
)
dest
:
*
(
DWORD64
*
)
dest
;
print_address
(
&
a
,
TRUE
);
break
;
}
}
a
.
Offset
=
addr
;
print_address_symbol
(
&
a
,
TRUE
,
instr
.
info
.
operand_count_visible
>
1
?
" ;"
:
""
);
break
;
}
}
addr
->
Offset
+=
instr
.
info
.
length
;
}
BOOL
memory_disasm_one_insn
(
ADDRESS64
*
addr
)
{
char
ch
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment