ReactOS  0.4.13-dev-99-g7e18b6d
disassembler.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 2000-2001 Goran Devic
4 Modified (c) 2001 Klaus P. Gerlicher
5 
6 Module Name:
7 
8  disassembler.c
9 
10 Abstract:
11 
12  line disassembler
13 
14 Environment:
15 
16  LINUX 2.2.X
17  Kernel mode only
18 
19 Author:
20 
21  Goran Devic
22 
23 Revision History:
24 
25  17-Mar-2000: Original (Goran Devic)
26  26-Apr-2000: Major rewrite, added coprocessor instructions (Goran Devic)
27  04-Nov-2000: Modified for LinIce (Goran Devic)
28  05-Jan-2001: Modified for pICE (Klaus P. Gerlicher)
29 
30 
31 Copyright notice:
32 
33  This file may be distributed under the terms of the GNU Public License.
34 
35 --*/
36 
37 /*******************************************************************************
38 * Include Files *
39 ******************************************************************************/
40 #include "remods.h"
41 #include "precomp.h"
42 
43 #include "disassemblerdata.h" // Include its own data
44 
45 /******************************************************************************
46 *
47 * This structure is used to pass parameters and options to the
48 * line disassembler.
49 *
50 ******************************************************************************/
51 typedef struct
52 {
53  ULONG dwFlags; // Generic flags (described below)
54  USHORT wSel; // Selector to use to fetch code
55  UCHAR *bpTarget; // Target pointer to disassemble
56  UCHAR *szDisasm; // String where to put ascii result
57  UCHAR Codes[20]; // Buffer where to store code UCHARs
58 
59  UCHAR bAsciiLen; // Length of the ascii result
60  UCHAR bInstrLen; // Instruction length in UCHARs
61 
62  int nDisplacement; // Scanner: possible constant displacement
63  int nScanEnum; // Scanner: specific flags SCAN_*
64 
66 
67 // dwFlags contains a set of boolean flags with the following functionality
68 
69 #define DIS_DATA32 0x0001 // Data size 16/32 bits (0/1)
70 #define DIS_GETDATASIZE(flags) ((flags)&DIS_DATA32)
71 #define DIS_ADDRESS32 0x0002 // Address size 16/32 bits (0/1)
72 #define DIS_GETADDRSIZE(flags) (((flags)&DIS_ADDRESS32)?1:0)
73 
74 #define DIS_SEGOVERRIDE 0x0004 // Default segment has been overriden
75 
76 #define DIS_REP 0x0100 // Return: REP prefix found (followed by..)
77 #define DIS_REPNE 0x0200 // Return: REPNE prefix found
78 #define DIS_GETREPENUM(flags) (((flags)>>8)&3)
79 #define DIS_ILLEGALOP 0x8000 // Return: illegal opcode
80 
81 
82 /******************************************************************************
83 * *
84 * Global Variables *
85 * *
86 ******************************************************************************/
87 
88 
89 /******************************************************************************
90 * *
91 * External functions (optional) *
92 * *
93 ******************************************************************************/
94 
95 /******************************************************************************
96 * *
97 * Local Defines, Variables and Macros *
98 * *
99 ******************************************************************************/
101 {
102  if(IsAddressValid(addr))
103  return *(PUCHAR)addr;
104  else
105  return 0x82; // INVALID OPCODE
106 }
107 
108 static UCHAR GetNextUCHAR(USHORT sel, UCHAR *offset, UCHAR *pCode)
109 {
110  pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF;
111 
112  return( pCode[0] );
113 }
114 
116 {
117  pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF;
118  pCode[1] = GetUCHAR((ULONG) offset + 1) & 0xFF;
119 
120  return( *(USHORT *) pCode );
121 }
122 
123 static ULONG GetNextULONG(USHORT sel, UCHAR *offset, UCHAR *pCode)
124 {
125  pCode[0] = GetUCHAR((ULONG) offset + 0) & 0xFF;
126  pCode[1] = GetUCHAR((ULONG) offset + 1) & 0xFF;
127  pCode[2] = GetUCHAR((ULONG) offset + 2) & 0xFF;
128  pCode[3] = GetUCHAR((ULONG) offset + 3) & 0xFF;
129 
130  return( *(ULONG *) pCode );
131 }
132 
133 
134 #define NEXTUCHAR GetNextUCHAR( pDis->wSel, bpTarget, bpCode); bpCode += 1; bpTarget += 1; bInstrLen += 1
135 
136 #define NEXTUSHORT GetNextUSHORT( pDis->wSel, bpTarget, bpCode); bpCode += 2; bpTarget += 2; bInstrLen += 2
137 
138 #define NEXTULONG GetNextULONG(pDis->wSel, bpTarget, bpCode); bpCode += 4; bpTarget += 4; bInstrLen += 4
139 
140 
141 /******************************************************************************
142 * *
143 * Functions *
144 * *
145 ******************************************************************************/
146 
147 /******************************************************************************
148 * *
149 * UCHAR Disassembler( TDisassembler *pDis ); *
150 * *
151 *******************************************************************************
152 *
153 * This is a generic Intel line disassembler.
154 *
155 * Where:
156 * TDisassembler:
157 * bpTarget is the address of instruction to disassemble
158 * szDisasm is the address of the buffer to print a line into
159 * dwFlags contains the default operand and address bits
160 * pCode is the address to store code UCHARs (up to 16)
161 *
162 * Disassembled instruction is stored as an ASCIIZ string pointed by
163 * szDisasm pointer (from the pDis structure).
164 *
165 * Returns:
166 * TDisassembler:
167 * *szDisasm contains the disassembled instruction string
168 * bAsciiLen is set to the length of the printed string
169 * bInstrLen is set to instruction length in UCHARs
170 * dwFlags - has operand and address size flags adjusted
171 * - DIS_ILLEGALOP set if that was illegal instruction
172 * UCHAR - instruction length in UCHARs
173 *
174 ******************************************************************************/
176 {
177  TOpcodeData *p; // Pointer to a current instruction record
178  UCHAR *bpTarget; // Pointer to the target code to be disassembled
179  UCHAR *bpCode; // Pointer to code UCHARs
180  ULONG arg; // Argument counter
181  char *sPtr; // Message selection pointer
182  int nPos; // Printing position in the output string
183  UCHAR *pArg; // Pointer to record where instruction arguments are
184  ULONG dwULONG; // Temporary ULONG storage
185  USHORT wUSHORT; // Temporary USHORT storage
186  UCHAR bUCHAR; // Temporary UCHAR storage
187  UCHAR bInstrLen; // Current instruction length in UCHARs
188  UCHAR bOpcode; // Current opcode that is being disassembled
189  UCHAR bSegOverride; // 0 default segment. >0, segment index
190  UCHAR bMod=0; // Mod field of the instruction
191  UCHAR bReg=0; // Register field of the instruction
192  UCHAR bRm=0; // R/M field of the instruction
193  UCHAR bW; // Width bit for the register selection
194 
195  UCHAR bSib; // S-I-B UCHAR for the instruction
196  UCHAR bSs; // SS field of the s-i-b UCHAR
197  UCHAR bIndex; // Index field of the s-i-b UCHAR
198  UCHAR bBase; // Base field of the s-i-b UCHAR
199  LPSTR pSymbolName; // used to symbolic name of value
200 
201  bInstrLen = 0; // Reset instruction length to zero
202  bSegOverride = 0; // Set default segment (no override)
203  nPos = 0; // Reset printing position
204  sPtr = NULL; // Points to no message by default
205  bpTarget = pDis->bpTarget; // Set internal pointer to a target address
206  bpCode = pDis->Codes; // Set internal pointer to code UCHARs
207 
208  do
209  {
210  bOpcode = NEXTUCHAR; // Get the first opcode UCHAR from the target address
211  p = &Op1[bOpcode]; // Get the address of the instruction record
212 
213  if( p->flags & DIS_SPECIAL )
214  {
215  // Opcode is one of the special ones, so do what needs to be done there
216 
217  switch( p->name )
218  {
219  case _EscD8:
220  case _EscD9:
221  case _EscDA:
222  case _EscDB:
223  case _EscDC:
224  case _EscDD:
225  case _EscDE:
226  case _EscDF: // Coprocessor escape: UCHARs D8 - DF
227  bOpcode = NEXTUCHAR; // Get the modRM UCHAR of the instruction
228 
229  if( bOpcode < 0xC0 )
230  {
231  // Opcodes 00-BF use Coproc1 table
232 
233  bReg = (bOpcode >> 3) & 7;
234  p = &Coproc1[ p->name - _EscD8 ][ bReg ];
235 
236  goto StartInstructionParseMODRM;
237  }
238  // Opcodes C0-FF use Coproc2 table
239 
240  p = &Coproc2[ p->name - _EscD8 ][ bOpcode - 0xC0 ];
241 
242  goto StartInstructionNoMODRM;
243 
244  case _S_ES: // Segment override
245  case _S_CS:
246  case _S_SS:
247  case _S_DS:
248  case _S_FS:
249  case _S_GS:
250  bSegOverride = p->name - _S_ES + 1;
251  continue;
252 
253  case _OPSIZ: // Operand size override - toggle
254  pDis->dwFlags ^= DIS_DATA32;
255  continue;
256 
257  case _ADSIZ: // Address size override - toggle
258  pDis->dwFlags ^= DIS_ADDRESS32;
259  continue;
260 
261  case _REPNE: // REPNE/REPNZ prefix
262  pDis->dwFlags |= DIS_REPNE;
263  continue;
264 
265  case _REP: // REP/REPE/REPZ prefix
266  pDis->dwFlags |= DIS_REP;
267  continue;
268 
269  case _2BESC: // 2 UCHAR escape code 0x0F
270  bOpcode = NEXTUCHAR; // Get the second UCHAR of the instruction
271  p = &Op2[bOpcode]; // Get the address of the instruction record
272 
273  if( !(p->flags & DIS_SPECIAL) ) goto StartInstruction;
274  if( p->name < _GRP6 ) goto IllegalOpcode;
275 
276  case _GRP1a: // Additional groups of instructions
277  case _GRP1b:
278  case _GRP1c:
279  case _GRP2a:
280  case _GRP2b:
281  case _GRP2c:
282  case _GRP2d:
283  case _GRP2e:
284  case _GRP2f:
285  case _GRP3a:
286  case _GRP3b:
287  case _GRP4:
288  case _GRP5:
289  case _GRP6:
290  case _GRP7:
291  case _GRP8:
292  case _GRP9:
293 
294  bOpcode = NEXTUCHAR; // Get the Mod R/M UCHAR whose...
295  // bits 3,4,5 select instruction
296 
297  bReg = (bOpcode >> 3) & 7;
298  p = &Groups[p->name - _GRP1a][ bReg ];
299 
300  if( !(p->flags & DIS_SPECIAL) ) goto StartInstructionParseMODRM;
301 
302  case _NDEF : // Not defined or illegal opcode
303  goto IllegalOpcode;
304 
305  default :; // Should not happen
306  }
307  }
308  else
309  goto StartInstruction;
310  }
311  while( bInstrLen < 15 );
312 
313 IllegalOpcode:
314 
315  nPos += PICE_sprintf( pDis->szDisasm+nPos, "invalid");
316  pDis->dwFlags |= DIS_ILLEGALOP;
317 
318  goto DisEnd;
319 
320 StartInstruction:
321 
322  // If this instruction needs additional Mod R/M UCHAR, fetch it
323 
324  if( p->flags & DIS_MODRM )
325  {
326  // Get the next UCHAR (modR/M bit field)
327  bOpcode = NEXTUCHAR;
328 
329  bReg = (bOpcode >> 3) & 7;
330 
331 StartInstructionParseMODRM:
332 
333  // Parse that UCHAR and get mod, reg and rm fields
334  bMod = bOpcode >> 6;
335  bRm = bOpcode & 7;
336  }
337 
338 StartInstructionNoMODRM:
339 
340  // Print the possible repeat prefix followed by the instruction
341 
342  if( p->flags & DIS_COPROC )
343  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%-6s ", sCoprocNames[ p->name ]);
344  else
345  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s%-6s ",
346  sRep[DIS_GETREPENUM(pDis->dwFlags)],
347  sNames[ p->name + (DIS_GETNAMEFLAG(p->flags) & DIS_GETDATASIZE(pDis->dwFlags)) ] );
348 
349  // Do instruction argument processing, up to 3 times
350 
351  pArg = &p->dest;
352 
353  for( arg=p->args; arg!=0; arg--, pArg++, arg? nPos += PICE_sprintf( pDis->szDisasm+nPos,", ") : 0 )
354  {
355  switch( *pArg )
356  {
357  case _Eb : // modR/M used - bW = 0
358  bW = 0;
359  goto _E;
360 
361  case _Ev : // modR/M used - bW = 1
362  bW = 1;
363  goto _E;
364 
365  case _Ew : // always USHORT size
366  pDis->dwFlags &= ~DIS_DATA32;
367  bW = 1;
368  goto _E;
369 
370  case _Ms : // fword ptr (sgdt,sidt,lgdt,lidt)
371  sPtr = sFwordPtr;
372  goto _E1;
373 
374  case _Mq : // qword ptr (cmpxchg8b)
375  sPtr = sQwordPtr;
376  goto _E1;
377 
378  case _Mp : // 32 or 48 bit pointer (les,lds,lfs,lss,lgs)
379  case _Ep : // Always a memory pointer (call, jmp)
380  if( pDis->dwFlags & DIS_DATA32 )
381  sPtr = sFwordPtr;
382  else
383  sPtr = sDwordPtr;
384  goto _E1;
385 
386  _E:
387  // Do registers first so that the rest may be done together
388  if( bMod == 3 )
389  {
390  // Registers depending on the w field and data size
391  nPos+=PICE_sprintf(pDis->szDisasm+nPos, "%s", sRegs1[DIS_GETDATASIZE(pDis->dwFlags)][bW][bRm] );
392 
393  break;
394  }
395 
396  if( bW==0 )
397  sPtr = sBytePtr;
398  else
399  if( pDis->dwFlags & DIS_DATA32 )
400  sPtr = sDwordPtr;
401  else
402  sPtr = sWordPtr;
403 
404  case _M : // Pure memory pointer (lea,invlpg,floats)
405  if( bMod == 3 ) goto IllegalOpcode;
406 
407  _E1:
408 
409  if( sPtr )
410  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sPtr );
411 
412  case _Ma : // Used by bound instruction, skip the pointer info
413 
414  // Print the segment if it is overriden
415  //
416  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sSegOverride[ bSegOverride ] );
417 
418  //
419  // Special case when sib UCHAR is present in 32 address encoding
420  //
421  if( (bRm==4) && (pDis->dwFlags & DIS_ADDRESS32) )
422  {
423  //
424  // Get the s-i-b UCHAR and parse it
425  //
426  bSib = NEXTUCHAR;
427 
428  bSs = bSib >> 6;
429  bIndex = (bSib >> 3) & 7;
430  bBase = bSib & 7;
431 
432  // Special case for base=5 && mod==0 -> fetch 32 bit offset
433  if( (bBase==5) && (bMod==0) )
434  {
435  dwULONG = NEXTULONG;
436  if(ScanExportsByAddress(&pSymbolName,dwULONG))
437  {
438  nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s", pSymbolName );
439  }
440  else
441  {
442  nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%08X", (unsigned int) dwULONG );
443  }
444  }
445  else
446  nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s", sGenReg16_32[ 1 ][ bBase ] );
447 
448  // Scaled index, no index if bIndex is 4
449  if( bIndex != 4 )
450  nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%s%s", sScale[ bSs ], sGenReg16_32[ 1 ][ bIndex ] );
451  else
452  if(bSs != 0)
453  nPos += PICE_sprintf( pDis->szDisasm+nPos,"<INVALID MODE>" );
454 
455  // Offset 8 bit or 32 bit
456  if( bMod == 1 )
457  {
458  bUCHAR = NEXTUCHAR;
459  if( (signed char)bUCHAR < 0 )
460  nPos += PICE_sprintf( pDis->szDisasm+nPos,"-%02X", 0-(signed char)bUCHAR );
461  else
462  nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%02X", bUCHAR );
463  }
464 
465  if( bMod == 2 )
466  {
467  dwULONG = NEXTULONG;
468  nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%08X", (unsigned int) dwULONG );
469  }
470 
471  // Wrap up the instruction
472  nPos += PICE_sprintf( pDis->szDisasm+nPos,"]" );
473  break;
474  }
475 
476  //
477  // 16 or 32 address bit cases with mod zero, one or two
478  //
479  // Special cases when r/m is 5 and mod is 0, immediate d16 or d32
480  if( bMod==0 && ((bRm==6 && !(pDis->dwFlags & DIS_ADDRESS32)) || (bRm==5 && (pDis->dwFlags & DIS_ADDRESS32))) )
481  {
482  if( pDis->dwFlags & DIS_ADDRESS32 )
483  {
484  dwULONG = NEXTULONG;
485  if(ScanExportsByAddress(&pSymbolName,dwULONG))
486  nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s]", pSymbolName );
487  else
488  nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%08X]", (unsigned int) dwULONG );
489  }
490  else
491  {
492  wUSHORT = NEXTUSHORT;
493  nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%04X]", wUSHORT );
494  }
495 
496  break;
497  }
498 
499  // Print the start of the line
500  nPos += PICE_sprintf( pDis->szDisasm+nPos,"[%s", sAdr1[DIS_GETADDRSIZE(pDis->dwFlags)][ bRm ] );
501 
502  // Offset (8 or 16) or (8 or 32) bit - 16, 32 bits are unsigned
503  if( bMod==1 )
504  {
505  bUCHAR = NEXTUCHAR;
506  if( (signed char)bUCHAR < 0 )
507  nPos += PICE_sprintf( pDis->szDisasm+nPos,"-%02X", 0-(signed char)bUCHAR );
508  else
509  nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%02X", bUCHAR );
510  }
511 
512  if( bMod==2 )
513  {
514  if( pDis->dwFlags & DIS_ADDRESS32 )
515  {
516  dwULONG = NEXTULONG;
517  nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%08X", (unsigned int) dwULONG );
518  }
519  else
520  {
521  wUSHORT = NEXTUSHORT;
522  nPos += PICE_sprintf( pDis->szDisasm+nPos,"+%04X", wUSHORT );
523  }
524  }
525 
526  // Wrap up the instruction
527  nPos += PICE_sprintf( pDis->szDisasm+nPos,"]" );
528 
529  break;
530 
531  case _Gb : // general, UCHAR register
532  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sRegs1[0][0][ bReg ] );
533  break;
534 
535  case _Gv : // general, (d)USHORT register
536  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[DIS_GETDATASIZE(pDis->dwFlags)][ bReg ] );
537  break;
538 
539  case _Yb : // ES:(E)DI pointer
540  case _Yv :
541  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s%s", sSegOverrideDefaultES[ bSegOverride ], sYptr[DIS_GETADDRSIZE(pDis->dwFlags)] );
542  break;
543 
544  case _Xb : // DS:(E)SI pointer
545  case _Xv :
546  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s%s", sSegOverrideDefaultDS[ bSegOverride ], sXptr[DIS_GETADDRSIZE(pDis->dwFlags)] );
547  break;
548 
549  case _Rd : // general register double USHORT
550  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[ 1 ][ bRm ] );
551  break;
552 
553  case _Rw : // register USHORT
554  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[ 0 ][ bMod ] );
555  break;
556 
557  case _Sw : // segment register
558  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sSeg[ bReg ] );
559  break;
560 
561  case _Cd : // control register
562  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sControl[ bReg ] );
563  break;
564 
565  case _Dd : // debug register
566  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sDebug[ bReg ] );
567  break;
568 
569  case _Td : // test register
570  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sTest[ bReg ] );
571  break;
572 
573 
574  case _Jb : // immediate UCHAR, relative offset
575  bUCHAR = NEXTUCHAR;
576  nPos += PICE_sprintf( pDis->szDisasm+nPos, "short %08X", (unsigned int)(pDis->bpTarget + (signed char)bUCHAR + bInstrLen) );
577  break;
578 
579  case _Jv : // immediate USHORT or ULONG, relative offset
580  if( pDis->dwFlags & DIS_DATA32 )
581  {
582  dwULONG = NEXTULONG;
583  if(ScanExportsByAddress(&pSymbolName,(unsigned int)(pDis->bpTarget + (signed long)dwULONG + bInstrLen)))
584  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", pSymbolName );
585  else
586  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int)(pDis->bpTarget + (signed long)dwULONG + bInstrLen) );
587  }
588  else
589  {
590  wUSHORT = NEXTUSHORT;
591  if(ScanExportsByAddress(&pSymbolName,(unsigned int)(pDis->bpTarget + (signed short)wUSHORT + bInstrLen)))
592  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", pSymbolName );
593  else
594  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int)(pDis->bpTarget + (signed short)wUSHORT + bInstrLen) );
595  }
596  break;
597 
598  case _O : // Simple USHORT or ULONG offset
599  if( pDis->dwFlags & DIS_ADDRESS32 ) // depending on the address size
600  {
601  dwULONG = NEXTULONG;
602  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s[%08X]", sSegOverride[ bSegOverride ], (unsigned int) dwULONG );
603  }
604  else
605  {
606  wUSHORT = NEXTUSHORT;
607  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s[%04X]", sSegOverride[ bSegOverride ], wUSHORT );
608  }
609  break;
610 
611  case _Ib : // immediate UCHAR
612  bUCHAR = NEXTUCHAR;
613  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%02X", bUCHAR );
614  break;
615 
616  case _Iv : // immediate USHORT or ULONG
617  if( pDis->dwFlags & DIS_DATA32 )
618  {
619  dwULONG = NEXTULONG;
620  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int) dwULONG );
621  }
622  else
623  {
624  wUSHORT = NEXTUSHORT;
625  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%04X", wUSHORT );
626  }
627  break;
628 
629  case _Iw : // Immediate USHORT
630  wUSHORT = NEXTUSHORT;
631  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%04X", wUSHORT );
632  break;
633 
634  case _Ap : // 32 bit or 48 bit pointer (call far, jump far)
635  if( pDis->dwFlags & DIS_DATA32 )
636  {
637  dwULONG = NEXTULONG;
638  wUSHORT = NEXTUSHORT;
639  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%04X:%08X", wUSHORT, (unsigned int) dwULONG );
640  }
641  else
642  {
643  dwULONG = NEXTULONG;
644  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%08X", (unsigned int) dwULONG );
645  }
646  break;
647 
648  case _1 : // numerical 1
649  nPos += PICE_sprintf( pDis->szDisasm+nPos,"1" );
650  break;
651 
652  case _3 : // numerical 3
653  nPos += PICE_sprintf( pDis->szDisasm+nPos,"3" );
654  break;
655 
656  // Hard coded registers
657  case _DX: case _AL: case _AH: case _BL: case _BH: case _CL: case _CH:
658  case _DL: case _DH: case _CS: case _DS: case _ES: case _SS: case _FS:
659  case _GS:
660  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sRegs2[ *pArg - _DX ] );
661  break;
662 
663  case _eAX: case _eBX: case _eCX: case _eDX:
664  case _eSP: case _eBP: case _eSI: case _eDI:
665  nPos += PICE_sprintf( pDis->szDisasm+nPos, "%s", sGenReg16_32[DIS_GETDATASIZE(pDis->dwFlags)][ *pArg - _eAX ]);
666  break;
667 
668  case _ST: // Coprocessor ST
669  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sST[9] );
670  break;
671 
672  case _ST0: // Coprocessor ST(0) - ST(7)
673  case _ST1:
674  case _ST2:
675  case _ST3:
676  case _ST4:
677  case _ST5:
678  case _ST6:
679  case _ST7:
680  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sST[ *pArg - _ST0 ] );
681  break;
682 
683  case _AX: // Coprocessor AX
684  nPos += PICE_sprintf( pDis->szDisasm+nPos,"%s", sGenReg16_32[0][0] );
685  break;
686  }
687  }
688 
689 DisEnd:
690 
691  // Set the returning values and return with the bInstrLen field
692 
693  pDis->bAsciiLen = (UCHAR) nPos;
694  pDis->bInstrLen = bInstrLen;
695 
696  return bInstrLen;
697 }
698 
699 /******************************************************************************
700 * *
701 * BOOLEAN Disasm(PULONG pOffset,PUCHAR pchDst) *
702 * *
703 * entry point for disassembly from other modules *
704 ******************************************************************************/
705 BOOLEAN Disasm(PULONG pOffset,PUCHAR pchDst)
706 {
707  TDisassembler dis;
708 
710  dis.bpTarget = (UCHAR*)*pOffset;
711  dis.szDisasm = pchDst;
712  dis.wSel = CurrentCS;
713 
714  *pOffset += (ULONG)Disassembler( &dis);
715  return TRUE;
716 }
#define _ST
USHORT CurrentCS
Definition: shell.c:116
#define _GRP1c
#define _GRP6
#define _Ep
char * name
Definition: wpp.c:36
#define _Jb
#define _EscDF
#define _S_GS
#define _EscDE
#define _Cd
#define _GRP1a
char * sBytePtr
#define TRUE
Definition: types.h:120
char * sSegOverrideDefaultDS[8]
#define _ST1
#define _ADSIZ
#define _eSI
#define _Xb
#define _Ew
#define _2BESC
#define _Iw
char * sYptr[2]
char * sScale[4]
#define _eBP
#define _1
char * sXptr[2]
unsigned char * PUCHAR
Definition: retypes.h:3
int PICE_sprintf(char *buf, const char *fmt,...)
Definition: utils.c:2053
#define _Yb
GLintptr offset
Definition: glext.h:5920
#define _BH
char * sDebug[8]
#define _DH
#define _GRP3b
char * sSegOverrideDefaultES[8]
#define _DX
#define DIS_COPROC
#define _eBX
void * arg
Definition: msvc.h:12
#define _ST0
TOpcodeData Groups[17][8]
char * LPSTR
Definition: xmlstorage.h:182
char * sSegOverride[8]
UCHAR GetUCHAR(ULONG addr)
Definition: disassembler.c:100
#define _GRP7
#define DIS_ILLEGALOP
Definition: disassembler.c:79
char * sControl[8]
#define _SS
#define _Gb
static ULONG GetNextULONG(USHORT sel, UCHAR *offset, UCHAR *pCode)
Definition: disassembler.c:123
#define _GRP9
char * sRegs1[2][2][8]
#define _Xv
#define _DS
char * sAdr1[2][8]
#define _ST2
#define _Ap
#define _GRP4
#define _eDX
#define DIS_GETREPENUM(flags)
Definition: disassembler.c:78
#define _EscDD
char * sNames[]
#define _GS
#define _EscDC
TOpcodeData Coproc2[8][16 *4]
UCHAR * bpTarget
Definition: disassembler.c:55
#define _GRP2f
#define _GRP2c
#define DIS_REPNE
Definition: disassembler.c:77
#define _S_CS
#define _EscD8
char * sDwordPtr
#define _AX
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _Ma
#define _FS
TOpcodeData Op1[256]
#define _GRP3a
#define _AL
#define _Mq
#define _Sw
#define _S_ES
#define DIS_SPECIAL
#define _S_DS
#define _Rw
#define DIS_GETADDRSIZE(flags)
Definition: disassembler.c:72
char * sGenReg16_32[2][8]
#define DIS_REP
Definition: disassembler.c:76
#define _Yv
#define _GRP2b
#define _Td
#define _CS
#define _eAX
#define _EscDB
#define _OPSIZ
#define _GRP2a
char * sTest[8]
#define _S_SS
#define DIS_MODRM
#define _REP
#define _GRP2e
static USHORT GetNextUSHORT(USHORT sel, UCHAR *offset, UCHAR *pCode)
Definition: disassembler.c:115
unsigned char UCHAR
Definition: xmlstorage.h:181
#define NEXTUCHAR
Definition: disassembler.c:134
GLenum const GLvoid * addr
Definition: glext.h:9621
#define _GRP2d
#define _S_FS
#define _Iv
BOOLEAN Disasm(PULONG pOffset, PUCHAR pchDst)
Definition: disassembler.c:705
#define DIS_ADDRESS32
Definition: disassembler.c:71
#define _Rd
char * sFwordPtr
#define _Ib
#define _3
#define _NDEF
char * sRep[4]
#define _Eb
#define _O
#define _BL
#define _ST5
#define DIS_DATA32
Definition: disassembler.c:69
#define _Gv
unsigned short USHORT
Definition: pedump.c:61
#define _GRP1b
char * sST[9]
char * sSeg[8]
_CH
Definition: saxreader.c:162
#define _GRP8
unsigned int * PULONG
Definition: retypes.h:1
#define _M
#define _ST6
#define DIS_GETNAMEFLAG(flags)
TOpcodeData Coproc1[8][8]
#define _ST3
#define _ST7
#define _ES
UCHAR Disassembler(TDisassembler *pDis)
Definition: disassembler.c:175
#define _Jv
char * sRegs2[]
#define _GRP5
char * sCoprocNames[]
unsigned int ULONG
Definition: retypes.h:1
#define _EscD9
#define _Mp
#define _EscDA
BOOLEAN ScanExportsByAddress(LPSTR *pFind, ULONG ulValue)
Definition: symbols.c:599
#define _eSP
#define NEXTUSHORT
Definition: disassembler.c:136
#define _eCX
#define _REPNE
#define _AH
GLfloat GLfloat p
Definition: glext.h:8902
#define NEXTULONG
Definition: disassembler.c:138
#define _ST4
#define _DL
#define _Dd
#define _CL
UCHAR * szDisasm
Definition: disassembler.c:56
#define _eDI
#define _Ev
BOOLEAN IsAddressValid(ULONG address)
Definition: utils.c:611
#define _Ms
char * sWordPtr
#define DIS_GETDATASIZE(flags)
Definition: disassembler.c:70
char * sQwordPtr
UCHAR Codes[20]
Definition: disassembler.c:57
TOpcodeData Op2[256]
static UCHAR GetNextUCHAR(USHORT sel, UCHAR *offset, UCHAR *pCode)
Definition: disassembler.c:108