summaryrefslogtreecommitdiffstats
path: root/private/mvdm/vdmexts/disasm.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/vdmexts/disasm.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/mvdm/vdmexts/disasm.c')
-rw-r--r--private/mvdm/vdmexts/disasm.c2407
1 files changed, 2407 insertions, 0 deletions
diff --git a/private/mvdm/vdmexts/disasm.c b/private/mvdm/vdmexts/disasm.c
new file mode 100644
index 000000000..04fa0c4c2
--- /dev/null
+++ b/private/mvdm/vdmexts/disasm.c
@@ -0,0 +1,2407 @@
+/*++
+
+Copyright (c) 1995 Microsoft Corporation
+
+Module Name:
+
+ disasm.c
+
+Abstract:
+
+ This file contains the x86 disassmbler invoked by "!bde.u <16:16 address>"
+
+Author:
+
+ Barry Bond (BarryBo)
+
+Revision History:
+
+ 09-May-1995 Barry Bond (BarryBo) Created
+ 15-Jan-1996 Neil Sandlin (NeilSa) Merged with vdmexts
+ 32 bit segments fixes
+
+--*/
+
+#include <precomp.h>
+#pragma hdrstop
+
+WORD gSelector = 0;
+ULONG gOffset = 0;
+
+VOID
+u(
+ CMD_ARGLIST
+) {
+ VDMCONTEXT ThreadContext;
+ WORD selector;
+ ULONG offset;
+ int mode;
+ char rgchOutput[128];
+ char rgchExtra[128];
+ BYTE rgbInstruction[64];
+ CHAR sym_text[255];
+ CHAR sym_prev[255] = "";
+ DWORD dist;
+ int cb;
+ int i;
+ int j;
+ int count=10;
+ ULONG Base;
+ SELECTORINFO si;
+
+ CMD_INIT();
+
+ mode = GetContext( &ThreadContext );
+
+ if (!GetNextToken()) {
+ if (!gSelector && !gOffset) {
+ selector = (WORD) ThreadContext.SegCs;
+ offset = ThreadContext.Eip;
+ } else {
+ selector = gSelector;
+ offset = gOffset;
+ }
+ } else if (!ParseIntelAddress(&mode, &selector, &offset)) {
+ return;
+ }
+
+ if (GetNextToken()) {
+ count = (int) EXPRESSION(lpArgumentString);
+ }
+
+ if ( mode != PROT_MODE && mode != V86_MODE) {
+ PRINTF(" Disassembly of flat mode code not allowed.\n");
+ return;
+ }
+
+ Base = GetInfoFromSelector( selector, mode, &si ) + GetIntelBase();
+
+ for (i=0; i<count; ++i) {
+
+ if (FindSymbol(selector, offset, sym_text, &dist, BEFORE, mode )) {
+ if (_stricmp(sym_text, sym_prev)) {
+ if ( dist == 0 ) {
+ PRINTF("%s:\n", sym_text );
+ } else {
+ PRINTF("%s+0x%lx:\n", sym_text, dist );
+ }
+ strcpy(sym_prev, sym_text);
+ }
+ }
+
+ cb = sizeof(rgbInstruction);
+ if ((DWORD)(offset+cb) >= si.Limit)
+ cb -= offset+cb-si.Limit;
+ if (!READMEM((LPVOID)(Base+offset), rgbInstruction, cb)) {
+ PRINTF("%04x:%08x: <Error Reading Memory>\n", selector, offset);
+ return;
+ }
+
+ cb = unassemble_one(rgbInstruction,
+ si.bBig,
+ selector, offset,
+ rgchOutput,
+ rgchExtra,
+ &ThreadContext,
+ mode);
+
+ if (offset > 0xffff) {
+ PRINTF("%04x:%08x ", selector, offset);
+ } else {
+ PRINTF("%04x:%04x ", selector, offset);
+ }
+
+ for (j=0; j<cb; ++j)
+ PRINTF("%02x", rgbInstruction[j]);
+ for (; j<8; ++j)
+ PRINTF(" ");
+ PRINTF("%s\t%s\n", rgchOutput, rgchExtra);
+
+ offset+=cb;
+ }
+}
+
+
+typedef struct _ADDR {
+ ULONG sOff;
+ USHORT sSeg;
+} ADDR;
+
+
+LPBYTE checkprefixes(LPBYTE);
+void AppendPrefixes(void);
+void DisplayAddress(int mod, int rm, int sOff, int size);
+
+#define modrmB 1
+#define modrmW 2
+#define reg1B 3
+#define reg1W 4
+#define reg2B 5
+#define reg2W 6
+#define eeeControl 7
+#define eeeDebug 8
+#define eeeTest 9
+#define regSeg 10
+#define ALreg 11
+#define AHreg 12
+#define BLreg 13
+#define BHreg 14
+#define CLreg 15
+#define CHreg 16
+#define DLreg 17
+#define DHreg 18
+#define AXreg 19
+#define BXreg 20
+#define CXreg 21
+#define DXreg 22
+#define SIreg 23
+#define DIreg 24
+#define SPreg 25
+#define BPreg 26
+#define CSreg 27
+#define SSreg 28
+#define DSreg 29
+#define ESreg 30
+#define FSreg 31
+#define GSreg 32
+#define ImmB 33
+#define ImmBEnter 34
+#define ImmBS 35
+#define ImmW 36
+#define ImmW1 37
+#define jmpB 38
+#define jmpW 39
+#define memB 40
+#define memW 41
+#define memD 42
+#define indirmodrmW 43
+#define indirFARmodrmW 44
+#define memB1 45
+
+
+int DmodrmB(LPBYTE);
+int DmodrmW(LPBYTE);
+int Dreg1B(LPBYTE);
+int Dreg1W(LPBYTE);
+int Dreg2B(LPBYTE);
+int Dreg2W(LPBYTE);
+int DeeeControl(LPBYTE);
+int DeeeDebug(LPBYTE);
+int DeeeTest(LPBYTE);
+int DregSeg(LPBYTE);
+int DALreg(LPBYTE);
+int DAHreg(LPBYTE);
+int DBLreg(LPBYTE);
+int DBHreg(LPBYTE);
+int DCLreg(LPBYTE);
+int DCHreg(LPBYTE);
+int DDLreg(LPBYTE);
+int DDHreg(LPBYTE);
+int DAXreg(LPBYTE);
+int DBXreg(LPBYTE);
+int DCXreg(LPBYTE);
+int DDXreg(LPBYTE);
+int DSIreg(LPBYTE);
+int DDIreg(LPBYTE);
+int DSPreg(LPBYTE);
+int DBPreg(LPBYTE);
+int DCSreg(LPBYTE);
+int DSSreg(LPBYTE);
+int DDSreg(LPBYTE);
+int DESreg(LPBYTE);
+int DFSreg(LPBYTE);
+int DGSreg(LPBYTE);
+int DImmB(LPBYTE);
+int DImmBEnter(LPBYTE);
+int DImmBS(LPBYTE);
+int DImmW(LPBYTE);
+int DImmW1(LPBYTE); // immediate-16 for 1-byte instructions
+int DjmpB(LPBYTE);
+int DjmpW(LPBYTE);
+int DmemB(LPBYTE);
+int DmemB1(LPBYTE);
+int DmemW(LPBYTE);
+int DmemD(LPBYTE);
+int DindirmodrmW(LPBYTE);
+int DindirFARmodrmW(LPBYTE);
+
+struct {
+ int (*pfn)(LPBYTE);
+} rgpfn[] = {
+
+ 0, // 0th entry is reserved
+ DmodrmB,
+ DmodrmW,
+ Dreg1B,
+ Dreg1W,
+ Dreg2B,
+ Dreg2W,
+ DeeeControl,
+ DeeeDebug,
+ DeeeTest,
+ DregSeg,
+ DALreg,
+ DAHreg,
+ DBLreg,
+ DBHreg,
+ DCLreg,
+ DCHreg,
+ DDLreg,
+ DDHreg,
+ DAXreg,
+ DBXreg,
+ DCXreg,
+ DDXreg,
+ DSIreg,
+ DDIreg,
+ DSPreg,
+ DBPreg,
+ DCSreg,
+ DSSreg,
+ DDSreg,
+ DESreg,
+ DFSreg,
+ DGSreg,
+ DImmB,
+ DImmBEnter,
+ DImmBS,
+ DImmW,
+ DImmW1, // immediate-16 for 1-byte instructions
+ DjmpB,
+ DjmpW,
+ DmemB,
+ DmemW,
+ DmemD,
+ DindirmodrmW,
+ DindirFARmodrmW,
+ DmemB1
+};
+
+VDMCONTEXT *g_pThreadContext;
+int g_mode;
+char *g_pchOutput; // the disassembled instruction
+char *g_pchExtra; // contents of memory (if any) modified by this instr.
+int prefixes;
+
+//NOTE: if first byte = 0x0f, then the instruction is two bytes long
+
+char *szRegsB[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
+char *szRegsW[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
+char *szRegsD[] = {"eax","ecx","edx","ebx","esp","ebp","esi","edi"};
+char *szRegsSeg[] = {"es", "cs", "ss", "ds", "fs", "gs", "(bad)", "(bad)"};
+char *szMod[] = {"[bx+si", "[bx+di", "[bp+si", "[bp+di", "[si", "[di", "[bp", "[bx"};
+
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADR 0x400
+#define PREFIX_FWAIT 0x800
+
+#define GROUP_1B -1
+#define GROUP_1WS -2
+#define GROUP_1W -3
+#define GROUP_2B -4
+#define GROUP_2W -5
+#define GROUP_2B_1 -6
+#define GROUP_2W_1 -7
+#define GROUP_2B_CL -8
+#define GROUP_2W_CL -9
+#define GROUP_3B -10
+#define GROUP_3W -11
+#define GROUP_4 -12
+#define GROUP_5 -13
+#define GROUP_6 -14
+#define GROUP_7 -15
+#define GROUP_8 -16
+
+#define FLOATCODE -51
+#define FLOAT FLOATCODE
+
+// WARNING: This list must remain in sync with the szInstructions[] array
+#define szAdc 1
+#define szAdd 2
+#define szAnd 3
+#define szBad 4
+#define szCmp 5
+#define szDec 6
+#define szIn 7
+#define szInc 8
+#define szJmp 9
+#define szMov 10
+#define szOr 11
+#define szOut 12
+#define szRcl 13
+#define szRcr 14
+#define szRol 15
+#define szRor 16
+#define szSar 17
+#define szSbb 18
+#define szShl 19
+#define szShr 20
+#define szSub 21
+#define szTest 22
+#define szPop 23
+#define szPush 24
+#define szXchg 25
+#define szXor 26
+#define szDaa 27
+#define szDas 28
+#define szPusha 29
+#define szPopa 30
+#define szBound 31
+#define szArpl 32
+#define szAaa 33
+#define szAas 34
+#define szImul 35
+#define szIdiv 36
+#define szJo 37
+#define szJno 38
+#define szJb 39
+#define szJae 40
+#define szJe 41
+#define szJne 42
+#define szJbe 43
+#define szJa 44
+#define szJs 45
+#define szJns 46
+#define szJp 47
+#define szJnp 48
+#define szJl 49
+#define szJnl 50
+#define szJle 51
+#define szJg 52
+#define szNop 53
+#define szLea 54
+#define szCbw 55
+#define szCwd 56
+#define szCall 57
+#define szPushf 58
+#define szPopf 59
+#define szSahf 60
+#define szLahf 61
+#define szMovsb 62
+#define szMovsw 63
+#define szCmpsb 64
+#define szCmpsw 65
+#define szStosb 66
+#define szStosw 67
+#define szLodsb 68
+#define szLodsw 69
+#define szScasb 70
+#define szScasw 71
+#define szRetn 72
+#define szLes 73
+#define szLds 74
+#define szEnter 75
+#define szLeave 76
+#define szRetf 77
+#define szInt3 78
+#define szInt 79
+#define szInto 80
+#define szIret 81
+#define szAam 82
+#define szAad 83
+#define szXlat 84
+#define szLoopne 85
+#define szLoope 86
+#define szLoop 87
+#define szJcxz 88
+#define szHalt 89
+#define szCmc 90
+#define szClc 91
+#define szStc 92
+#define szCli 93
+#define szSti 94
+#define szCld 95
+#define szStd 96
+#define szLar 97
+#define szLsl 98
+#define szClts 99
+#define szSeto 100
+#define szSetno 101
+#define szSetb 102
+#define szSetae 103
+#define szSete 104
+#define szSetne 105
+#define szSetbe 106
+#define szSeta 107
+#define szSets 108
+#define szSetns 109
+#define szSetp 110
+#define szSetnp 111
+#define szSetl 112
+#define szSetge 113
+#define szSetle 114
+#define szSetg 115
+#define szBt 116
+#define szShld 117
+#define szBts 118
+#define szShrd 119
+#define szShdr 120
+#define szLss 121
+#define szBtr 122
+#define szLfs 123
+#define szLgs 124
+#define szMovzx 125
+#define szBtc 126
+#define szBsf 127
+#define szBsr 128
+#define szMovsx 129
+#define szNot 130
+#define szNeg 131
+#define szMul 132
+#define szDiv 133
+#define szSldt 134
+#define szStr 135
+#define szLldt 136
+#define szLtr 137
+#define szVerr 138
+#define szVerw 139
+#define szSgdt 140
+#define szSidt 141
+#define szLgdt 142
+#define szLidt 143
+#define szSmsw 144
+#define szLmsw 145
+
+// WARNING: This must stay in sync with the #define list above
+char *szInstructions[] = {
+ "", //used to indicate groups
+ "adc",
+ "add",
+ "and",
+ "(bad)",
+ "cmp",
+ "dec",
+ "in",
+ "inc",
+ "jmp",
+ // 10
+ "mov",
+ "or",
+ "out",
+ "rcl",
+ "rcr",
+ "rol",
+ "ror",
+ "sar",
+ "sbb",
+ "shl",
+ // 20
+ "shr",
+ "sub",
+ "test",
+ "pop",
+ "push",
+ "xchg",
+ "xor",
+ "daa",
+ "das",
+ "pusha",
+ // 30
+ "popa",
+ "bound",
+ "arpl",
+ "aaa",
+ "aas",
+ "imul",
+ "idiv",
+ "jo",
+ "jno",
+ "jb",
+ // 40
+ "jae",
+ "je",
+ "jne",
+ "jbe",
+ "ja",
+ "js",
+ "jns",
+ "jp",
+ "jnp",
+ "jl",
+ // 50
+ "jnl",
+ "jle",
+ "jg",
+ "nop",
+ "lea",
+ "cbw",
+ "cwd",
+ "call",
+ "pushf",
+ "popf",
+ // 60
+ "sahf",
+ "lahf",
+ "movsb",
+ "movsw",
+ "cmpsb",
+ "cmpsw",
+ "stosb",
+ "stosw",
+ "lodsb",
+ "lodsw",
+ // 70
+ "scasb",
+ "scasw",
+ "retn",
+ "les",
+ "lds",
+ "enter",
+ "leave",
+ "retf",
+ "int3",
+ "int",
+ // 80
+ "into",
+ "iret",
+ "aam",
+ "aad",
+ "xlat",
+ "loopne",
+ "loope",
+ "loop",
+ "jcxz",
+ "halt",
+ // 90
+ "cmc",
+ "clc",
+ "stc",
+ "cli",
+ "sti",
+ "cld",
+ "std",
+ "lar",
+ "lsl",
+ "clts",
+ // 100
+ "seto",
+ "setno",
+ "setb",
+ "setae",
+ "sete",
+ "setne",
+ "setbe",
+ "seta",
+ "sets",
+ "setns",
+ // 110
+ "setp",
+ "setnp",
+ "setl",
+ "setge",
+ "setle",
+ "setg",
+ "bt",
+ "shld",
+ "bts",
+ "shrd",
+ // 120
+ "shdr",
+ "lss",
+ "btr",
+ "lfs",
+ "lgs",
+ "movzx",
+ "btc",
+ "bsf",
+ "bsr",
+ "movsx",
+ // 130
+ "not",
+ "neg",
+ "mul",
+ "div",
+ "sldt",
+ "str",
+ "lldt",
+ "ltr",
+ "verr",
+ "verw",
+ // 140
+ "sgdt",
+ "sidt",
+ "lgdt",
+ "lidt",
+ "smsw",
+ "lmsw"
+};
+
+struct dis {
+ int szName;
+ char iPart1;
+ char iPart2;
+ char iPart3;
+};
+
+struct dis dis386[] = {
+ // 0
+ { szAdd, modrmB, reg1B },
+ { szAdd, modrmW, reg1W },
+ { szAdd, reg1B, modrmB },
+ { szAdd, reg1W, modrmW },
+ { szAdd, ALreg, ImmB },
+ { szAdd, AXreg, ImmW },
+ { szPush, ESreg },
+ { szPop, ESreg},
+ // 8
+ { szOr, modrmB, reg1B },
+ { szOr, modrmW, reg1W },
+ { szOr, reg1B, modrmB },
+ { szOr, reg1W, modrmW },
+ { szOr, ALreg, ImmB },
+ { szOr, AXreg, ImmW },
+ { szPush, CSreg },
+ { szBad }, // 0x0f is the 2-byte instr prefix
+ // 10
+ { szAdc, modrmB, reg1B },
+ { szAdc, modrmW, reg1W },
+ { szAdc, reg1B, modrmB },
+ { szAdc, reg1W, modrmW },
+ { szAdc, ALreg, ImmB },
+ { szAdc, AXreg, ImmW },
+ { szPush, SSreg },
+ { szPop, SSreg },
+ // 18
+ { szSbb, modrmB, reg1B },
+ { szSbb, modrmW, reg1W },
+ { szSbb, reg1B, modrmB },
+ { szSbb, reg1W, modrmW },
+ { szSbb, ALreg, ImmB },
+ { szSbb, AXreg, ImmW },
+ { szPush, DSreg },
+ { szPop, DSreg },
+ // 20
+ { szAnd, modrmB, reg1B },
+ { szAnd, modrmW, reg1W },
+ { szAnd, reg1B, modrmB },
+ { szAnd, reg1W, modrmW },
+ { szAnd, ALreg, ImmB },
+ { szAnd, AXreg, ImmW },
+ { szBad }, // ES override prefix
+ { szDaa },
+ // 28
+ { szSub, modrmB, reg1B },
+ { szSub, modrmW, reg1W },
+ { szSub, reg1B, modrmB },
+ { szSub, reg1W, modrmW },
+ { szSub, ALreg, ImmB },
+ { szSub, AXreg, ImmW },
+ { szBad }, // CS override prefix
+ { szDas },
+ // 30
+ { szXor, modrmB, reg1B },
+ { szXor, modrmW, reg1W },
+ { szXor, reg1B, modrmB },
+ { szXor, reg1W, modrmW },
+ { szXor, ALreg, ImmB },
+ { szXor, AXreg, ImmW },
+ { szBad}, // SS override prefix
+ { szAaa },
+ // 38
+ { szCmp, modrmB, reg1B },
+ { szCmp, modrmW, reg1W },
+ { szCmp, reg1B, modrmB },
+ { szCmp, reg1W, modrmW },
+ { szCmp, ALreg, ImmB },
+ { szCmp, AXreg, ImmW },
+ { szBad },
+ { szAas },
+ // 40
+ { szInc, AXreg },
+ { szInc, CXreg },
+ { szInc, DXreg },
+ { szInc, BXreg },
+ { szInc, SPreg },
+ { szInc, BPreg },
+ { szInc, SIreg },
+ { szInc, DIreg },
+ // 48
+ { szDec, AXreg },
+ { szDec, CXreg },
+ { szDec, DXreg },
+ { szDec, BXreg },
+ { szDec, SPreg },
+ { szDec, BPreg },
+ { szDec, SIreg },
+ { szDec, DIreg },
+ // 50
+ { szPush, AXreg },
+ { szPush, CXreg },
+ { szPush, DXreg },
+ { szPush, BXreg },
+ { szPush, SPreg },
+ { szPush, BPreg },
+ { szPush, SIreg },
+ { szPush, DIreg },
+ // 58
+ { szPop, AXreg },
+ { szPop, CXreg },
+ { szPop, DXreg },
+ { szPop, BXreg },
+ { szPop, SPreg },
+ { szPop, BPreg },
+ { szPop, SIreg },
+ { szPop, DIreg },
+ // 60
+ { szPusha },
+ { szPopa },
+ { szBound, reg1W, modrmW },
+ { szArpl, reg1W, reg2W },
+ { szBad }, // FS segment override
+ { szBad }, // GS segment override
+ { szBad }, // op size prefix
+ { szBad }, // addr size prefix
+ // 68
+ { szPush, ImmW},
+ { szImul, reg1W, modrmW },
+ { szPush, ImmBS},
+ { szImul, reg1B, modrmB },
+ { szIn, ImmB, DXreg },
+ { szIn, ImmW, DXreg },
+ { szOut, ImmB, DXreg },
+ { szOut, ImmW, DXreg },
+ // 70
+ { szJo, jmpB },
+ { szJno, jmpB },
+ { szJb, jmpB },
+ { szJae, jmpB },
+ { szJe, jmpB },
+ { szJne, jmpB },
+ { szJbe, jmpB },
+ { szJa, jmpB },
+ // 78
+ { szJs, jmpB },
+ { szJns, jmpB },
+ { szJp, jmpB },
+ { szJnp, jmpB },
+ { szJl, jmpB },
+ { szJnl, jmpB },
+ { szJle, jmpB },
+ { szJg, jmpB },
+ // 80
+ { GROUP_1B },
+ { GROUP_1W },
+ { szBad },
+ { GROUP_1WS },
+ { szTest, reg1B, modrmB },
+ { szTest, reg1W, modrmW },
+ { szXchg, reg1B, modrmB },
+ { szXchg, reg1W, modrmW },
+ // 88
+ { szMov, modrmB, reg1B },
+ { szMov, modrmW, reg1W },
+ { szMov, reg1B, modrmB },
+ { szMov, reg1W, modrmW },
+ { szMov, modrmW, regSeg },
+ { szLea, reg1W, modrmW },
+ { szMov, regSeg, modrmW },
+ { szPop, modrmW },
+ // 90
+ { szNop },
+ { szXchg, AXreg, CXreg },
+ { szXchg, AXreg, DXreg },
+ { szXchg, AXreg, BXreg },
+ { szXchg, AXreg, SPreg },
+ { szXchg, AXreg, BPreg },
+ { szXchg, AXreg, SIreg },
+ { szXchg, AXreg, DIreg },
+ // 98
+ { szCbw },
+ { szCwd },
+ { szCall, memD },
+ { szBad },
+ { szPushf },
+ { szPopf },
+ { szSahf },
+ { szLahf },
+ // a0
+ { szMov, ALreg, memB },
+ { szMov, AXreg, memW },
+ { szMov, memB, ALreg },
+ { szMov, memW, AXreg },
+ { szMovsb },
+ { szMovsw },
+ { szCmpsb },
+ { szCmpsw },
+ // a8
+ { szTest, ALreg, memB },
+ { szTest, AXreg, memW },
+ { szStosb },
+ { szStosw },
+ { szLodsb },
+ { szLodsw },
+ { szScasb },
+ { szScasw },
+ // b0
+ { szMov, ALreg, ImmB },
+ { szMov, CLreg, ImmB },
+ { szMov, DLreg, ImmB },
+ { szMov, BLreg, ImmB },
+ { szMov, AHreg, ImmB },
+ { szMov, CHreg, ImmB },
+ { szMov, DHreg, ImmB },
+ { szMov, BHreg, ImmB },
+ // b8
+ { szMov, AXreg, ImmW },
+ { szMov, CXreg, ImmW },
+ { szMov, DXreg, ImmW },
+ { szMov, BXreg, ImmW },
+ { szMov, SPreg, ImmW },
+ { szMov, BPreg, ImmW },
+ { szMov, SIreg, ImmW },
+ { szMov, DIreg, ImmW },
+ // c0
+ { GROUP_2B },
+ { GROUP_2W },
+ { szRetn, ImmW },
+ { szRetn },
+ { szLes, reg1W, modrmW },
+ { szLds, reg1W, modrmW },
+ { szMov, modrmB, ImmB },
+ { szMov, modrmW, ImmW },
+ // c8
+ { szEnter, ImmW, ImmBEnter },
+ { szLeave },
+ { szRetf, ImmW1 },
+ { szRetf },
+ { szInt3 },
+ { szInt, ImmB },
+ { szInto },
+ { szIret },
+ // d0
+ { GROUP_2B_1 },
+ { GROUP_2W_1 },
+ { GROUP_2B_CL },
+ { GROUP_2W_CL },
+ { szAam, ImmB },
+ { szAad, ImmB },
+ { szBad },
+ { szXlat },
+ // d8
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ // e0
+ { szLoopne, jmpB },
+ { szLoope, jmpB },
+ { szLoop, jmpB },
+ { szJcxz, jmpB },
+ { szIn, ALreg, memB1 },
+ { szIn, AXreg, memB1 },
+ { szOut, memB1, ALreg },
+ { szOut, memB1, AXreg },
+ // e8
+ { szCall, jmpW },
+ { szJmp, jmpW },
+ { szJmp, memD },
+ { szJmp, jmpB },
+ { szIn, ALreg, DXreg },
+ { szIn, AXreg, DXreg },
+ { szOut, DXreg, ALreg },
+ { szOut, DXreg, AXreg },
+ // f0
+ { szBad }, // lock prefix
+ { szBad },
+ { szBad }, // repne prefix
+ { szBad }, // repz prefix
+ { szHalt },
+ { szCmc },
+ { GROUP_3B },
+ { GROUP_3W },
+ // f8
+ { szClc },
+ { szStc },
+ { szCli },
+ { szSti },
+ { szCld },
+ { szStd },
+ { GROUP_4 },
+ { GROUP_5 },
+};
+
+
+struct dis dis386_2[] = {
+ // 00
+ { GROUP_6 },
+ { GROUP_7 },
+ { szLar, reg1W, modrmW },
+ { szLsl, reg1W, modrmW },
+ { szBad },
+ { szBad },
+ { szClts },
+ { szBad },
+ // 08
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 10
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 18
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 20
+ { szMov, reg2W, eeeControl },
+ { szMov, reg2W, eeeDebug },
+ { szMov, eeeControl, reg2W },
+ { szMov, eeeDebug, reg2W },
+ { szMov, reg2W, eeeTest },
+ { szBad },
+ { szMov, eeeTest, reg2W },
+ { szBad },
+ // 28
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 30
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 38
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 40
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 48
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 50
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 58
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 60
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 68
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 70
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 78
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // 80
+ { szJo, jmpW },
+ { szJno, jmpW },
+ { szJb, jmpW },
+ { szJae, jmpW },
+ { szJe, jmpW },
+ { szJne, jmpW },
+ { szJbe, jmpW },
+ { szJa, jmpW },
+ // 88
+ { szJs, jmpW },
+ { szJns, jmpW },
+ { szJp, jmpW },
+ { szJnp, jmpW },
+ { szJl, jmpW },
+ { szJnl, jmpW },
+ { szJle, jmpW },
+ { szJg, jmpW },
+ // 90
+ { szSeto, modrmB },
+ { szSetno, modrmB },
+ { szSetb, modrmB },
+ { szSetae, modrmB },
+ { szSete, modrmB },
+ { szSetne, modrmB },
+ { szSetbe, modrmB },
+ { szSeta, modrmB },
+ // 98
+ { szSets, modrmB },
+ { szSetns, modrmB },
+ { szSetp, modrmB },
+ { szSetnp, modrmB },
+ { szSetl, modrmB },
+ { szSetge, modrmB },
+ { szSetle, modrmB },
+ { szSetg, modrmB },
+ // a0
+ { szPush, FSreg },
+ { szPop, FSreg },
+ { szBad },
+ { szBt, modrmW, reg1W },
+ { szShld, reg1W, modrmW, ImmB },
+ { szShld, reg1W, modrmW, CLreg },
+ { szBad },
+ { szBad },
+ // a8
+ { szPush, GSreg },
+ { szPop, GSreg },
+ { szBad },
+ { szBts, modrmW, reg1W },
+ { szShrd, reg1W, modrmW, ImmB },
+ { szShdr, reg1W, modrmW, CLreg },
+ { szBad },
+ { szImul, reg1W, modrmW },
+ // b0
+ { szBad },
+ { szBad },
+ { szLss, reg1W, modrmW },
+ { szBtr, modrmW, reg1W },
+ { szLfs, reg1W, modrmW },
+ { szLgs, reg1W, modrmW },
+ { szMovzx, reg1B, modrmB },
+ { szMovzx, reg1W, modrmW },
+ // b8
+ { szBad },
+ { szBad },
+ { GROUP_8 },
+ { szBtc, modrmW, reg1W },
+ { szBsf, reg1W, modrmW },
+ { szBsr, reg1W, modrmW },
+ { szMovsx, reg1B, modrmB },
+ { szMovsx, reg1W, modrmW },
+ // c0
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // c8
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // d0
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // d8
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // e0
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // e8
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // f0
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ // f8
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+};
+
+struct dis dis386_groups[][8] = {
+ // GROUP_1B
+ {
+ { szAdd, modrmB, ImmB },
+ { szOr, modrmB, ImmB },
+ { szAdc, modrmB, ImmB },
+ { szSbb, modrmB, ImmB },
+ { szAnd, modrmB, ImmB },
+ { szSub, modrmB, ImmB },
+ { szXor, modrmB, ImmB },
+ { szCmp, modrmB, ImmB }
+ },
+ // GROUP_1WS
+ {
+ { szAdd, modrmW, ImmBS },
+ { szOr, modrmW, ImmBS },
+ { szAdc, modrmW, ImmBS },
+ { szSbb, modrmW, ImmBS },
+ { szAnd, modrmW, ImmBS },
+ { szSub, modrmW, ImmBS },
+ { szXor, modrmW, ImmBS },
+ { szCmp, modrmW, ImmBS }
+ },
+ // GROUP_1W
+ {
+ { szAdd, modrmW, ImmW },
+ { szOr, modrmW, ImmW },
+ { szAdc, modrmW, ImmW },
+ { szSbb, modrmW, ImmW },
+ { szAnd, modrmW, ImmW },
+ { szSub, modrmW, ImmW },
+ { szXor, modrmW, ImmW },
+ { szCmp, modrmW, ImmW }
+ },
+ // GROUP_2B
+ {
+ { szRol, modrmB, ImmB },
+ { szRor, modrmB, ImmB },
+ { szRcl, modrmB, ImmB },
+ { szRcr, modrmB, ImmB },
+ { szShl, modrmB, ImmB },
+ { szShr, modrmB, ImmB },
+ { szBad },
+ { szSar, modrmB, ImmB }
+ },
+ // GROUP_2W
+ {
+ { szRol, modrmW, ImmB },
+ { szRor, modrmW, ImmB },
+ { szRcl, modrmW, ImmB },
+ { szRcr, modrmW, ImmB },
+ { szShl, modrmW, ImmB },
+ { szShr, modrmW, ImmB },
+ { szBad },
+ { szSar, modrmW, ImmB }
+ },
+ // GROUP_2B_1
+ {
+ { szRol, modrmB },
+ { szRor, modrmB },
+ { szRcl, modrmB },
+ { szRcr, modrmB },
+ { szShl, modrmB },
+ { szShr, modrmB },
+ { szBad },
+ { szSar, modrmB }
+ },
+ // GROUP_2W_1
+ {
+ { szRol, modrmW },
+ { szRor, modrmW },
+ { szRcl, modrmW },
+ { szRcr, modrmW },
+ { szShl, modrmW },
+ { szShr, modrmW },
+ { szBad },
+ { szSar, modrmW }
+ },
+ // GROUP_2B_CL
+ {
+ { szRol, modrmB, CLreg },
+ { szRor, modrmB, CLreg },
+ { szRcl, modrmB, CLreg },
+ { szRcr, modrmB, CLreg },
+ { szShl, modrmB, CLreg },
+ { szShr, modrmB, CLreg },
+ { szBad },
+ { szSar, modrmB, CLreg }
+ },
+ // GROUP_2W_CL
+ {
+ { szRol, modrmW, CLreg },
+ { szRor, modrmW, CLreg },
+ { szRcl, modrmW, CLreg },
+ { szRcr, modrmW, CLreg },
+ { szShl, modrmW, CLreg },
+ { szShr, modrmW, CLreg },
+ { szBad },
+ { szSar, modrmW, CLreg }
+ },
+ // GROUP_3B
+ {
+ { szTest, modrmB, ImmB },
+ { szBad },
+ { szNot, modrmB },
+ { szNeg, modrmB },
+ { szMul, ALreg, modrmB },
+ { szImul, ALreg, modrmB },
+ { szDiv, ALreg, modrmB },
+ { szIdiv, ALreg, modrmB }
+ },
+ // GROUP_3W
+ {
+ { szTest, modrmW, ImmW },
+ { szBad },
+ { szNot, modrmW },
+ { szNeg, modrmW },
+ { szMul, AXreg, modrmW },
+ { szImul, AXreg, modrmW },
+ { szDiv, AXreg, modrmW },
+ { szIdiv, AXreg, modrmW }
+ },
+ // GROUP_4
+ {
+ { szInc, modrmB },
+ { szDec, modrmB },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad }
+ },
+ // GROUP_5
+ {
+ { szInc, modrmW },
+ { szDec, modrmW },
+ { szCall, indirmodrmW },
+ { szCall, indirFARmodrmW },
+ { szJmp, indirmodrmW },
+ { szJmp, indirFARmodrmW },
+ { szPush, modrmW },
+ { szBad }
+ },
+ // GROUP_6
+ {
+ { szSldt, modrmW },
+ { szStr, modrmW },
+ { szLldt, modrmW },
+ { szLtr, modrmW },
+ { szVerr, modrmW },
+ { szVerw, modrmW },
+ { szBad },
+ { szBad }
+ },
+ // GROUP_7
+ {
+ { szSgdt, modrmW },
+ { szSidt, modrmW },
+ { szLgdt, modrmW },
+ { szLidt, modrmW },
+ { szSmsw, modrmW },
+ { szBad },
+ { szLmsw, modrmW },
+ { szBad }
+ },
+ // GROUP_8
+ {
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBad },
+ { szBt, modrmW, ImmB },
+ { szBts, modrmW, ImmB },
+ { szBtr, modrmW, ImmB },
+ { szBtc, modrmW, ImmB }
+ }
+};
+
+UCHAR OpcodeSize;
+BYTE *pData;
+ADDR g_InstrAddr;
+BOOL bBig;
+
+void AppendString(char *str)
+{
+ strcpy(g_pchOutput, (str));
+ g_pchOutput+=strlen(g_pchOutput);
+}
+
+void ExtraString(char *str)
+{
+ strcpy(g_pchExtra, (str));
+ g_pchExtra+=strlen(g_pchExtra);
+}
+
+#define AppendChar(c) {*g_pchOutput++ = (c);}
+#define AppendNumber(d) {_ultoa((ULONG)d,g_pchOutput, 16); g_pchOutput+=strlen(g_pchOutput);}
+
+#define ExtraChar(c) {*g_pchExtra++ = (c);}
+#define ExtraNumber(d) {_ultoa((ULONG)d,g_pchExtra, 16); g_pchExtra+=strlen(g_pchExtra);}
+#define OPERAND_32 ((prefixes & PREFIX_DATA) ^ bBig)
+
+int unassemble_one(
+ BYTE *pInstrStart, // instruction to decode (can be local buffer)
+ BOOL bDefaultBig,
+ WORD wInstrSeg, // selector of instruction
+ DWORD dwInstrOff, // offset of instruction
+ char *pchOutput, // [out] disassembled instruction
+ char *pchExtra, // [out] extra info (ie. "es:[53]=1234")
+ // (can be NULL)
+ VDMCONTEXT *pThreadContext,
+ int mode
+) {
+ int i;
+ int cb;
+ BYTE *pInstr = pInstrStart;
+ struct dis *pszDecode;
+
+ g_pThreadContext = pThreadContext;
+ g_mode = mode;
+
+ g_pchOutput = pchOutput;
+ g_InstrAddr.sSeg = wInstrSeg;
+ g_InstrAddr.sOff = dwInstrOff;
+ bBig = bDefaultBig;
+
+ if (pchExtra)
+ *pchExtra = '\0';
+
+ g_pchExtra = pchExtra;
+
+ pInstr = checkprefixes(pInstr);
+
+ OpcodeSize = 1;
+
+ if (*pInstr == 0x0f) {
+ OpcodeSize++;
+ pInstr++;
+ pszDecode = &dis386_2[*pInstr];
+ } else {
+ pszDecode = &dis386[*pInstr];
+ }
+
+ if (prefixes & PREFIX_REPZ)
+ AppendString("repz ");
+ if (prefixes & PREFIX_REPNZ)
+ AppendString("repnz ");
+ if (prefixes & PREFIX_LOCK)
+ AppendString("lock ");
+ if ((prefixes & PREFIX_FWAIT) && ((*pInstr < 0xd8) || (*pInstr > 0xdf))) {
+ /* fwait not followed by floating point instruction */
+ AppendString("fwait");
+ return (1);
+ }
+
+ pInstr++;
+ pData = pInstr;
+ if (pszDecode->szName < 0) { // found a GROUP_ or FLOAT entry...
+ i = (-pszDecode->szName)-1;
+ if (i == FLOATCODE) {
+ //Later: mputs("Floating point instructions NYI\n");
+ return 1;
+ } else {
+ pszDecode = &dis386_groups[i][(*pInstr>>3)&7];
+ }
+ }
+
+ AppendString(szInstructions[pszDecode->szName]);
+
+ if (pszDecode->iPart1) {
+
+ AppendChar('\t');
+
+ i = (*(rgpfn[pszDecode->iPart1].pfn))(pInstr);
+
+ if (pszDecode->iPart2) {
+
+ AppendString(", ");
+ i+=(*(rgpfn[pszDecode->iPart2].pfn))(pInstr);
+
+ if (pszDecode->iPart3) {
+
+ AppendString(", ");
+ i+=(*(rgpfn[pszDecode->iPart3].pfn))(pInstr);
+
+ }
+ }
+
+ pInstr+=i;
+ }
+
+ AppendChar('\0');
+ cb = pInstr - pInstrStart; // return length of instruction
+
+ gSelector = wInstrSeg;
+ gOffset = dwInstrOff + cb;
+ return cb;
+}
+
+BOOL safe_read_byte(
+ ADDR addr,
+ BYTE *pb
+) {
+ ULONG Base;
+
+ *pb = 0xbb;
+ Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL );
+ if (Base == (ULONG)-1 || Base == 0) {
+ return FALSE;
+ }
+
+ Base += GetIntelBase();
+
+ return READMEM((LPVOID)(Base+(ULONG)addr.sOff), pb, 1);
+}
+
+BOOL safe_read_short(
+ ADDR addr,
+ SHORT *ps
+) {
+ ULONG Base;
+
+ Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL );
+ if (Base == (ULONG)-1 || Base == 0) {
+ return FALSE;
+ }
+
+ Base += GetIntelBase();
+
+ return READMEM((LPVOID)(Base+(ULONG)addr.sOff), ps, 2);
+}
+
+BOOL safe_read_long(
+ ADDR addr,
+ LONG *pl
+) {
+ ULONG Base;
+
+ Base = GetInfoFromSelector( addr.sSeg, g_mode, NULL );
+ if (Base == (ULONG)-1 || Base == 0) {
+ return FALSE;
+ }
+
+ Base += GetIntelBase();
+
+ return READMEM((LPVOID)(Base+(ULONG)addr.sOff), pl, 4);
+}
+
+
+int Dreg1B(LPBYTE lpB)
+{
+ BYTE b = (*lpB >> 3) & 7;
+
+ AppendString(szRegsB[b]);
+
+ return 0;
+}
+
+int Dreg1W(LPBYTE lpB)
+{
+ BYTE b = (*lpB >> 3) & 7;
+
+ if (OPERAND_32)
+ AppendString(szRegsD[b]);
+ else
+ AppendString(szRegsW[b]);
+
+ return 0;
+}
+
+int Dreg2B(LPBYTE lpB)
+{
+ BYTE b = *lpB & 7;
+
+ AppendString(szRegsB[b]);
+
+ return 0;
+}
+
+int Dreg2W(LPBYTE lpB)
+{
+ BYTE b = *lpB & 7;
+
+ if (OPERAND_32)
+ AppendString(szRegsD[b]);
+ else
+ AppendString(szRegsW[b]);
+
+ return 0;
+}
+
+int DmodrmB(LPBYTE lpB)
+{
+ BYTE rm = *lpB & 0x07;
+ BYTE mod = *lpB >> 6;
+ unsigned short num;
+ int iRet;
+
+ pData++; // skip past mod r/m
+ if (mod == 3) {
+ AppendPrefixes();
+ AppendString(szRegsB[rm]);
+ return 1;
+ }
+
+ iRet = 0;
+ AppendString("byte ptr ");
+ AppendPrefixes();
+ AppendString(szMod[rm]);
+ AppendChar('+');
+
+ switch (mod) {
+ case 0:
+ if (rm == 6) {
+ g_pchOutput-=3; // back up over the 'BP+'
+ num = *((UNALIGNED USHORT*)pData);
+ AppendNumber(num);
+ pData+=2;
+ iRet = 3;
+ } else {
+ num = 0;
+ g_pchOutput--;
+ iRet = 1;
+ }
+ break;
+
+ case 1:
+ num = *pData;
+ AppendNumber(num);
+ pData++;
+ iRet = 2;
+ break;
+
+ case 2:
+ num = *((UNALIGNED USHORT*)pData);
+ AppendNumber(num);
+ pData += 2;
+ iRet = 3;
+ break;
+ }
+
+ AppendChar(']');
+
+ DisplayAddress(mod, rm, num, 1);
+
+ return iRet;
+}
+
+int DmodrmW(LPBYTE lpB)
+{
+ BYTE rm = *lpB & 0x07;
+ BYTE mod = *lpB >> 6;
+ unsigned short num;
+ int iRet;
+
+ pData++; // skip past mod r/m
+ if (mod == 3) {
+ AppendPrefixes();
+ if (OPERAND_32)
+ AppendString(szRegsD[rm]);
+ else
+ AppendString(szRegsW[rm]);
+ return 1;
+ }
+
+ if (OPERAND_32) {
+ AppendString("dword ptr ");
+ AppendPrefixes();
+ AppendChar('[');
+ AppendString(szRegsD[rm]);
+ } else {
+ AppendString("word ptr ");
+ AppendPrefixes();
+ AppendString(szMod[rm]);
+ }
+ AppendChar('+');
+
+ switch (mod) {
+ case 0:
+ if (rm == 6) {
+ g_pchOutput-=3; // back up over 'BP+'
+ num = *((UNALIGNED USHORT*)pData);
+ AppendNumber(num);
+ pData+=2;
+ iRet = 3;
+ } else {
+ g_pchOutput--; // else back up over '+' alone
+ num=0;
+ iRet = 1;
+ }
+ break;
+
+ case 1:
+ num = *pData;
+ AppendNumber(num);
+ pData++;
+ iRet = 2;
+ break;
+
+ case 2:
+ num = *((UNALIGNED USHORT *)pData);
+ AppendNumber(num);
+ pData+=2;
+ iRet = 3;
+ break;
+ }
+
+ AppendChar(']');
+
+ if (OPERAND_32)
+ DisplayAddress(mod, rm, num, 4);
+ else
+ DisplayAddress(mod, rm, num, 2);
+
+ return iRet;
+}
+
+
+void DisplayAddress(int mod, int rm, int sOff, int size)
+{
+ ADDR addr;
+
+ // if caller of unassemble_one() didn't want extra info, return now
+ if (g_pchExtra == NULL)
+ return;
+
+ // no memory reference
+ if (mod == 3)
+ return;
+
+ // display prefix
+
+ if (prefixes & PREFIX_DS) {
+ ExtraChar('D');
+ addr.sSeg = (USHORT)g_pThreadContext->SegDs;
+ } else if (prefixes & PREFIX_ES) {
+ ExtraChar('E');
+ addr.sSeg = (USHORT)g_pThreadContext->SegEs;
+ } else if (prefixes & PREFIX_FS) {
+ ExtraChar('F');
+ addr.sSeg = (USHORT)g_pThreadContext->SegFs;
+ } else if (prefixes & PREFIX_GS) {
+ ExtraChar('G');
+ addr.sSeg = (USHORT)g_pThreadContext->SegGs;
+ } else if (prefixes & PREFIX_CS) {
+ ExtraChar('C');
+ addr.sSeg = (USHORT)g_pThreadContext->SegCs;
+ } else if ( (prefixes & PREFIX_SS) || rm==2 || rm == 3) {
+ ExtraChar('S');
+ addr.sSeg = (USHORT)g_pThreadContext->SegSs;
+ } else if (rm == 6 && mod != 0) {
+ ExtraChar('S');
+ addr.sSeg = (USHORT)g_pThreadContext->SegSs;
+ } else {
+ ExtraChar('D');
+ addr.sSeg = (USHORT)g_pThreadContext->SegDs;
+ }
+
+ ExtraString("S:[");
+
+ switch (rm) {
+ case 0:
+ addr.sOff = (USHORT)(g_pThreadContext->Ebx + g_pThreadContext->Esi);
+ break;
+
+ case 1:
+ addr.sOff = (USHORT)(g_pThreadContext->Ebx + g_pThreadContext->Edi);
+ break;
+
+ case 2:
+ addr.sOff = (USHORT)(g_pThreadContext->Ebp + g_pThreadContext->Esi);
+ break;
+
+ case 3:
+ addr.sOff = (USHORT)(g_pThreadContext->Ebp + g_pThreadContext->Edi);
+ break;
+
+ case 4:
+ addr.sOff = (USHORT)g_pThreadContext->Esi;
+ break;
+
+ case 5:
+ addr.sOff = (USHORT)g_pThreadContext->Edi;
+ break;
+
+ case 6:
+ if (mod == 0)
+ addr.sOff = 0;
+ else
+ addr.sOff = (USHORT)g_pThreadContext->Ebp;
+ break;
+
+ default:
+ addr.sOff = (USHORT)g_pThreadContext->Ebx;
+
+ }
+
+ addr.sOff += sOff;
+ ExtraNumber(addr.sOff);
+ ExtraString("]=");
+ if (size == 2) {
+ SHORT s;
+ if (safe_read_short(addr, &s)) {
+ ExtraNumber( s );
+ } else {
+ ExtraString("????");
+ }
+ } else if (size == 1) {
+ BYTE b;
+ if (safe_read_byte(addr, &b)) {
+ ExtraNumber( b );
+ } else {
+ ExtraString("??");
+ }
+ } else if (size == 4) {
+ LONG l;
+ if (safe_read_long(addr, &l)) {
+ ExtraNumber( l );
+ } else {
+ ExtraString("????????");
+ }
+ } else {
+ ExtraString("Unknown size!");
+ }
+}
+
+
+int DALreg(LPBYTE lpB)
+{
+ AppendString("al");
+
+ return 0;
+}
+
+int DAHreg(LPBYTE lpB)
+{
+ AppendString("ah");
+
+ return 0;
+}
+
+int DBLreg(LPBYTE lpB)
+{
+ AppendString("bl");
+
+ return 0;
+}
+
+int DBHreg(LPBYTE lpB)
+{
+ AppendString("bh");
+
+ return 0;
+}
+
+int DCLreg(LPBYTE lpB)
+{
+ AppendString("cl");
+
+ return 0;
+}
+
+int DCHreg(LPBYTE lpB)
+{
+ AppendString("ch");
+
+ return 0;
+}
+
+int DDLreg(LPBYTE lpB)
+{
+ AppendString("dl");
+
+ return 0;
+}
+
+int DDHreg(LPBYTE lpB)
+{
+ AppendString("dh");
+
+ return 0;
+}
+
+int DAXreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("ax");
+
+ return 0;
+}
+
+int DBXreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("bx");
+
+ return 0;
+}
+
+int DCXreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("cx");
+
+ return 0;
+}
+
+int DDXreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("dx");
+
+ return 0;
+}
+
+int DBPreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("bp");
+
+ return 0;
+}
+
+int DSPreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("sp");
+
+ return 0;
+}
+
+int DSIreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("si");
+
+ return 0;
+}
+
+int DDIreg(LPBYTE lpB)
+{
+ if (OPERAND_32)
+ AppendChar('e');
+
+ AppendString("di");
+
+ return 0;
+}
+
+int DCSreg(LPBYTE lpB)
+{
+ AppendString("cs");
+
+ return 0;
+}
+
+int DDSreg(LPBYTE lpB)
+{
+ AppendString("ds");
+
+ return 0;
+}
+
+int DSSreg(LPBYTE lpB)
+{
+ AppendString("es");
+
+ return 0;
+}
+
+int DESreg(LPBYTE lpB)
+{
+ AppendString("es");
+
+ return 0;
+}
+
+int DFSreg(LPBYTE lpB)
+{
+ AppendString("fs");
+
+ return 0;
+}
+
+int DGSreg(LPBYTE lpB)
+{
+ AppendString("gs");
+
+ return 0;
+}
+
+int DImmB(LPBYTE lpB)
+{
+ AppendNumber(*((UCHAR *)pData));
+ pData++;
+
+ return 1;
+}
+
+int DImmBEnter(LPBYTE lpB)
+{
+ AppendNumber(*((UCHAR *)pData));
+ pData++;
+
+ return 1;
+}
+
+int DImmBS(LPBYTE lpB) // sign-extend 8-bit value to 16 bits
+{
+ int i = (signed char)*(pData);
+
+ AppendNumber((USHORT)i);
+ pData++;
+
+ return 1;
+}
+
+int DImmW(LPBYTE lpB)
+{
+ if (OPERAND_32) {
+
+ AppendNumber( *((UNALIGNED ULONG*)pData) );
+ pData+=4;
+ return 4;
+
+ } else {
+
+ AppendNumber( *((UNALIGNED USHORT*)pData) );
+ pData+=2;
+ return 2;
+
+ }
+}
+
+int DImmW1(LPBYTE lpB)
+{
+ AppendNumber( *((UNALIGNED SHORT*)(pData)) );
+ pData++;
+
+ return 2;
+}
+
+int DjmpB(LPBYTE lpB)
+{
+ ULONG Dest = g_InstrAddr.sOff + (LONG)*((UNALIGNED CHAR *)lpB) + OpcodeSize + 1;
+
+ if (OPERAND_32) {
+ AppendNumber(Dest);
+ } else {
+ AppendNumber((USHORT)Dest);
+ }
+
+ return 1;
+}
+
+int DjmpW(LPBYTE lpB)
+{
+ ULONG Dest = g_InstrAddr.sOff + (ULONG)*((UNALIGNED USHORT *)lpB) + OpcodeSize + 2;
+
+ if (OPERAND_32) {
+ AppendNumber(Dest);
+ } else {
+ AppendNumber((USHORT)Dest);
+ }
+
+ return 2;
+}
+
+int DregSeg(LPBYTE lpB)
+{
+ BYTE b = (*lpB >> 3) & 7;
+
+ AppendString(szRegsSeg[b]);
+
+ return 0;
+}
+
+
+int DmemB(LPBYTE lpB)
+{
+ ADDR addr;
+
+ addr.sOff = *(lpB+1);
+
+ AppendChar('[');
+ AppendNumber( addr.sOff );
+ AppendChar(']');
+
+ if (g_pchExtra) {
+ BYTE b;
+
+ if (prefixes & PREFIX_DS) {
+ ExtraChar('D');
+ addr.sSeg = (USHORT)g_pThreadContext->SegDs;
+ } else if (prefixes & PREFIX_ES) {
+ ExtraChar('E');
+ addr.sSeg = (USHORT)g_pThreadContext->SegEs;
+ } else if (prefixes & PREFIX_FS) {
+ ExtraChar('F');
+ addr.sSeg = (USHORT)g_pThreadContext->SegFs;
+ } else if (prefixes & PREFIX_GS) {
+ ExtraChar('G');
+ addr.sSeg = (USHORT)g_pThreadContext->SegGs;
+ } else if (prefixes & PREFIX_CS) {
+ ExtraChar('C');
+ addr.sSeg = (USHORT)g_pThreadContext->SegCs;
+ } else if (prefixes & PREFIX_SS) {
+ ExtraChar('S');
+ addr.sSeg = (USHORT)g_pThreadContext->SegSs;
+ } else {
+ ExtraChar('D');
+ addr.sSeg = (USHORT)g_pThreadContext->SegDs;
+ }
+
+ ExtraString("S:[");
+ ExtraNumber( addr.sOff );
+ ExtraString("]=");
+ if (safe_read_byte(addr, &b)) {
+ ExtraNumber( b );
+ } else {
+ ExtraString("??");
+ }
+
+ }
+
+ return 1;
+}
+
+int DmemB1(LPBYTE lpB)
+{
+ AppendNumber( *lpB );
+
+ return 1;
+}
+
+int DmemW(LPBYTE lpB)
+{
+ int i;
+ ADDR addr;
+
+ addr.sOff = *(lpB+1);
+
+ AppendChar('[');
+ if (OPERAND_32) {
+ AppendNumber( *((UNALIGNED long*)lpB) );
+ i=4;
+ } else {
+ addr.sOff = *((UNALIGNED short *)lpB);
+ AppendNumber( addr.sOff );
+ i=2;
+ }
+ AppendChar(']');
+
+ if (g_pchExtra) {
+
+ if (prefixes & PREFIX_DS) {
+ ExtraChar('D');
+ addr.sSeg = (USHORT)g_pThreadContext->SegDs;
+ } else if (prefixes & PREFIX_ES) {
+ ExtraChar('E');
+ addr.sSeg = (USHORT)g_pThreadContext->SegEs;
+ } else if (prefixes & PREFIX_FS) {
+ ExtraChar('F');
+ addr.sSeg = (USHORT)g_pThreadContext->SegFs;
+ } else if (prefixes & PREFIX_GS) {
+ ExtraChar('G');
+ addr.sSeg = (USHORT)g_pThreadContext->SegGs;
+ } else if (prefixes & PREFIX_CS) {
+ ExtraChar('C');
+ addr.sSeg = (USHORT)g_pThreadContext->SegCs;
+ } else if (prefixes & PREFIX_SS) {
+ ExtraChar('S');
+ addr.sSeg = (USHORT)g_pThreadContext->SegSs;
+ } else {
+ ExtraChar('D');
+ addr.sSeg = (USHORT)g_pThreadContext->SegDs;
+ }
+
+ ExtraString("S:[");
+ ExtraNumber( addr.sOff );
+ ExtraString("]=");
+ if (i == 2) {
+ SHORT s;
+ if (safe_read_short(addr, &s)) {
+ ExtraNumber( s );
+ } else {
+ ExtraString( "????" );
+ }
+ } else {
+ LONG l;
+
+ if (safe_read_long(addr, &l)) {
+ ExtraNumber( l );
+ } else {
+ ExtraString( "????????" );
+ }
+ }
+ }
+
+ return i;
+}
+
+
+int DmemD(LPBYTE lpB)
+{
+ int i;
+
+ if (OPERAND_32) {
+ AppendNumber( *(((UNALIGNED SHORT*)lpB)+2) );
+ AppendChar(':');
+ AppendNumber( *((UNALIGNED long*)lpB) );
+ i=6;
+ } else {
+ USHORT sel, off;
+
+ sel = *(((UNALIGNED SHORT*)lpB)+1);
+ off = *((UNALIGNED SHORT*)lpB);
+ AppendNumber( sel );
+ AppendChar(':');
+ AppendNumber( off );
+ i=4;
+
+ if (g_pchExtra) {
+ char sym_text[1000];
+ LONG dist;
+
+ // if the exact symbol name was found, print it
+ if (FindSymbol( sel,
+ off,
+ sym_text,
+ &dist,
+ BEFORE,
+ g_mode)) {
+ ExtraString("= ");
+ ExtraString(sym_text);
+ if (dist) {
+ ExtraString(" + ");
+ ExtraNumber( dist );
+ }
+ }
+ }
+
+ }
+
+ return i;
+}
+
+int DindirmodrmW(LPBYTE lpB)
+{
+ int i;
+
+ AppendString("FAR PTR ");
+ i = DmodrmW(lpB);
+ AppendChar(']');
+
+ return i;
+}
+
+
+int DindirFARmodrmW(LPBYTE lpB)
+{
+ int i;
+
+ AppendString("FAR PTR ");
+ i = DmodrmW(lpB);
+ AppendChar(']');
+
+ return i;
+}
+
+
+int DeeeControl(LPBYTE lpB)
+{
+ AppendChar('c');
+ AppendChar('r');
+ AppendChar('0'+ ((*lpB >> 3) & 7) );
+
+ return 1;
+}
+
+int DeeeDebug(LPBYTE lpB)
+{
+ AppendChar('d');
+ AppendChar('r');
+ AppendChar('0'+ ((*lpB >> 3) & 7) );
+
+ return 1;
+}
+
+int DeeeTest(LPBYTE lpB)
+{
+ AppendChar('t');
+ AppendChar('r');
+ AppendChar('0'+ ((*lpB >> 3) & 7) );
+
+ return 1;
+}
+
+
+LPBYTE checkprefixes(LPBYTE lpB)
+{
+ prefixes = 0;
+
+ for (;;) {
+
+ switch (*lpB) {
+ case 0xf3:
+ prefixes |= PREFIX_REPZ;
+ break;
+ case 0xf2:
+ prefixes |= PREFIX_REPNZ;
+ break;
+ case 0xf0:
+ prefixes |= PREFIX_LOCK;
+ break;
+ case 0x2e:
+ prefixes |= PREFIX_CS;
+ break;
+ case 0x36:
+ prefixes |= PREFIX_SS;
+ break;
+ case 0x3e:
+ prefixes |= PREFIX_DS;
+ break;
+ case 0x26:
+ prefixes |= PREFIX_ES;
+ break;
+ case 0x64:
+ prefixes |= PREFIX_FS;
+ break;
+ case 0x65:
+ prefixes |= PREFIX_GS;
+ break;
+ case 0x66:
+ prefixes |= PREFIX_DATA;
+ break;
+ case 0x67:
+ prefixes |= PREFIX_ADR;
+ break;
+ case 0x9b:
+ prefixes |= PREFIX_FWAIT;
+ break;
+ default:
+ return lpB;
+ }
+ lpB++;
+ }
+}
+
+
+void AppendPrefixes(void)
+{
+ if (prefixes & PREFIX_CS)
+ AppendString("cs:");
+ if (prefixes & PREFIX_DS)
+ AppendString("ds:");
+ if (prefixes & PREFIX_SS)
+ AppendString("ss:");
+ if (prefixes & PREFIX_ES)
+ AppendString("es:");
+ if (prefixes & PREFIX_FS)
+ AppendString("fs:");
+ if (prefixes & PREFIX_GS)
+ AppendString("gs:");
+}