diff options
Diffstat (limited to 'private/mvdm/vdmexts/disasm.c')
-rw-r--r-- | private/mvdm/vdmexts/disasm.c | 2407 |
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:"); +} |