1 // Copyright (C) 2004, Matt Conover (mconover@gmail.com)
2 #undef NDEBUG
3 #include <assert.h>
4 #include "disasm.h"
5 #include "cpu.h"
6 
7 // Since addresses are internally represented as 64-bit, we need to specially handle
8 // cases where IP + Displacement wraps around for 16-bit/32-bit operand size
9 // Otherwise, ignorethe possibility of wraparounds
10 #define SUPPORT_WRAPAROUND
11 
12 #ifdef NO_SANITY_CHECKS
13 #undef NDEBUG
14 #undef DEBUG_DISASM
15 #undef assert
16 #define assert(x)
17 #endif
18 
19 #ifdef DEBUG_DISASM
20 #define DISASM_OUTPUT(x) printf x
21 #else
22 #define DISASM_OUTPUT(x)
23 #endif
24 
25 #include "disasm_x86_tables.h"
26 
27 #ifdef _WIN64
28 #ifdef _MSC_VER
29 #pragma warning(disable:4311 4312)
30 #endif
31 #endif
32 
33 ////////////////////////////////////////////////////////////////////////
34 // Internal macros
35 ////////////////////////////////////////////////////////////////////////
36 
37 #define VIRTUAL_ADDRESS ((U64)Instruction->Address + Instruction->VirtualAddressDelta)
38 
39 #define AMD64_DIFF (AMD64_8BIT_OFFSET-X86_8BIT_OFFSET)
40 #define IS_AMD64() (INS_ARCH_TYPE(Instruction) == ARCH_X64)
41 #define IS_X86_32() (INS_ARCH_TYPE(Instruction) == ARCH_X86)
42 #define IS_X86_16() (INS_ARCH_TYPE(Instruction) == ARCH_X86_16)
43 
44 #define X86_BOUND 0x62
45 #define X86_PUSH_REG 0x50
46 #define X86_PUSH_CS 0x0e
47 #define X86_PUSH_DS 0x1e
48 #define X86_PUSH_SS 0x16
49 #define X86_PUSH_ES 0x06
50 #define X86_PUSH_FS 0xa0
51 #define X86_PUSH_GS 0xa8
52 #define X86_PUSH_U8 0x6a
53 #define X86_PUSH_U32 0x68
54 #define X86_POP_DS 0x1f
55 #define X86_POP_ES 0x07
56 #define X86_POP_SS 0x17
57 #define X86_POP_FS 0xa1
58 #define X86_POP_GS 0xa9
59 #define X86_POP_REG 0x58
60 
61 #define OPCSTR Instruction->String+Instruction->StringIndex
62 #define APPEND Instruction->StringIndex += (U8)_snprintf
63 #define APPENDPAD(x) \
64 { \
65 	if (Instruction->StringAligned) \
66 	{  \
67 			if (Instruction->StringIndex > x) assert(0); \
68 			while (x != Instruction->StringIndex) APPENDB(' ');  \
69 	}  \
70 	else if (Instruction->StringIndex) \
71 	{  \
72 		APPENDB(' '); \
73 	} \
74 }
75 
76 #define APPENDB(a) Instruction->String[Instruction->StringIndex++] = a
77 #define APPENDS(a) APPEND(OPCSTR, SIZE_LEFT, a);
78 
79 #define SIZE_LEFT (MAX_OPCODE_DESCRIPTION-1 > Instruction->StringIndex ? MAX_OPCODE_DESCRIPTION-Instruction->StringIndex : 0)
80 
81 // If an address size prefix is used for an instruction that doesn't make sense, restore it
82 // to the default
83 
84 #define SANITY_CHECK_OPERAND_SIZE() \
85 { \
86 	if (!Instruction->AnomalyOccurred && X86Instruction->HasOperandSizePrefix) \
87 	{ \
88 		if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Unexpected operand size prefix\n", VIRTUAL_ADDRESS); \
89 		Instruction->AnomalyOccurred = TRUE; \
90 		X86Instruction->HasOperandSizePrefix = FALSE; \
91 		switch (X86Instruction->OperandSize) \
92 		{ \
93 			case 4: X86Instruction->OperandSize = 2; break; \
94 			case 2: X86Instruction->OperandSize = 4; break; \
95 			default: assert(0); \
96 		} \
97 	} \
98 }
99 
100 #define SANITY_CHECK_ADDRESS_SIZE() \
101 { \
102 	if (!Instruction->AnomalyOccurred && X86Instruction->HasAddressSizePrefix) \
103 	{ \
104 		if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Unexpected address size prefix\n", VIRTUAL_ADDRESS); \
105 		Instruction->AnomalyOccurred = TRUE; \
106 	} \
107 	X86Instruction->HasAddressSizePrefix = FALSE; \
108 	switch (INS_ARCH_TYPE(Instruction)) \
109 	{ \
110 		case ARCH_X64: X86Instruction->AddressSize = 8; break; \
111 		case ARCH_X86: X86Instruction->AddressSize = 4; break; \
112 		case ARCH_X86_16: X86Instruction->AddressSize = 2; break; \
113 	} \
114 }
115 
116 #define SANITY_CHECK_SEGMENT_OVERRIDE() \
117 	if (!Instruction->AnomalyOccurred && X86Instruction->HasSegmentOverridePrefix) \
118 	{ \
119 		if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Unexpected segment override\n", VIRTUAL_ADDRESS); \
120 		Instruction->AnomalyOccurred = TRUE; \
121 	}
122 
123 #define INSTR_INC(size) \
124 { \
125 	Instruction->Length += size; \
126 	Address += size; \
127 }
128 
129 #define X86_SET_TARGET() \
130 { \
131 	if (X86Instruction->HasSelector) \
132 	{ \
133 		if (!Instruction->AnomalyOccurred) \
134 		{ \
135 			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: unexpected segment 0x%02lX\n", VIRTUAL_ADDRESS, X86Instruction->Selector); \
136 			Instruction->AnomalyOccurred = TRUE; \
137 		} \
138 	} \
139 	else \
140 	{ \
141 		switch (X86Instruction->Segment) \
142 		{ \
143 			case SEG_CS: \
144 			case SEG_DS: \
145 			case SEG_SS: \
146 			case SEG_ES: \
147 				assert(!X86Instruction->HasSelector); \
148 				Operand->TargetAddress = (U64)X86Instruction->Displacement; \
149 				/* assert(!GetAbsoluteAddressFromSegment((BYTE)X86Instruction->Segment, (DWORD)X86Instruction->Displacement) || GetAbsoluteAddressFromSegment(X86Instruction->Segment, (DWORD)X86Instruction->Displacement) == Operand->TargetAddress); */ \
150 				break; \
151 			case SEG_FS: \
152 			case SEG_GS: \
153 				assert(!X86Instruction->HasSelector); \
154 				Operand->TargetAddress = (U64)GetAbsoluteAddressFromSegment((BYTE)X86Instruction->Segment, (DWORD)X86Instruction->Displacement); \
155 				break; \
156 			default: \
157 				assert(0); /* shouldn't be possible */ \
158 				break; \
159 		} \
160 	} \
161 }
162 
163 #define X86_SET_SEG(reg) \
164 { \
165 	if (!X86Instruction->HasSegmentOverridePrefix && (reg == REG_EBP || reg == REG_ESP)) \
166 	{ \
167 		assert(!X86Instruction->HasSelector); \
168 		X86Instruction->Segment = SEG_SS; \
169 	} \
170 }
171 
172 #define X86_SET_ADDR() \
173 { \
174 	if (Operand->Flags & OP_DST) \
175 	{ \
176 		assert(!X86Instruction->HasDstAddressing); \
177 		X86Instruction->HasDstAddressing = TRUE; \
178 		X86Instruction->DstOpIndex[X86Instruction->DstOpCount] = (U8)OperandIndex; \
179 		X86Instruction->DstOpCount++; \
180 		X86Instruction->DstAddressIndex = (U8)OperandIndex; \
181 	} \
182 	if (Operand->Flags & OP_SRC) \
183 	{ \
184 		if (Instruction->Type != ITYPE_STRCMP) assert(!X86Instruction->HasSrcAddressing); \
185 		X86Instruction->HasSrcAddressing = TRUE; \
186 		X86Instruction->SrcOpIndex[X86Instruction->SrcOpCount] = (U8)OperandIndex; \
187 		X86Instruction->SrcOpCount++; \
188 		X86Instruction->SrcAddressIndex = (U8)OperandIndex; \
189 	} \
190 }
191 
192 #define X86_SET_REG(reg) \
193 { \
194 	if (Operand->Flags & OP_DST) \
195 	{ \
196 		X86Instruction->DstOpIndex[X86Instruction->DstOpCount] = (U8)OperandIndex; \
197 		X86Instruction->DstOpCount++; \
198 		assert(OperandIndex < 2); \
199 		if (Operand->Length > 1 && reg == REG_ESP) Instruction->Groups |= ITYPE_STACK; \
200 	} \
201 	if (Operand->Flags & OP_SRC) \
202 	{ \
203 		X86Instruction->SrcOpIndex[X86Instruction->SrcOpCount] = (U8)OperandIndex; \
204 		X86Instruction->SrcOpCount++; \
205 	} \
206 }
207 
208 #define CHECK_AMD64_REG() { if (IS_AMD64()) Operand->Register += AMD64_DIFF; }
209 
210 ////////////////////////////////////////////////////////////////////////
211 // Internal structures/variables
212 ////////////////////////////////////////////////////////////////////////
213 
214 ARCHITECTURE_FORMAT_FUNCTIONS X86 =
215 {
216 	X86_InitInstruction,
217 	NULL,
218 	X86_GetInstruction,
219 	X86_FindFunctionByPrologue
220 };
221 
222 char *X86_Registers[0xE0] =
223 {
224 	// Segments
225 	"es", // 0x00
226 	"cs", // 0x01
227 	"ss", // 0x02
228 	"ds", // 0x03
229 	"fs", // 0x04
230 	"gs", // 0x05
231 	"flags", // 0x06
232 	"eflags", // 0x07
233 	"rflags", // 0x08
234 	"ip+ilen", // 0x09
235 	"eip+ilen", // 0x0A
236 	"rip+ilen", // 0x0B
237 	NULL, // 0x0C
238 	NULL, // 0x0D
239 	NULL, // 0x0E
240 	NULL, // 0x0F
241 
242 	// Test
243 	"tr0", // 0x10
244 	"tr1", // 0x11
245 	"tr2", // 0x12
246 	"tr3", // 0x13
247 	"tr4", // 0x14
248 	"tr5", // 0x15
249 	"tr6", // 0x16
250 	"tr7", // 0x17
251 	"tr8", // 0x18
252 	"tr9", // 0x19
253 	"tr10", // 0x1A
254 	"tr11", // 0x1B
255 	"tr12", // 0x1C
256 	"tr13", // 0x1D
257 	"tr14", // 0x1E
258 	"tr15", // 0x1F
259 
260 	// Control
261 	"cr0", // 0x20
262 	"cr1", // 0x21
263 	"cr2", // 0x22
264 	"cr3", // 0x23
265 	"cr4", // 0x24
266 	"cr5", // 0x25
267 	"cr6", // 0x26
268 	"cr7", // 0x27
269 	"cr8", // 0x18
270 	"cr9", // 0x19
271 	"cr10", // 0x1A
272 	"cr11", // 0x1B
273 	"cr12", // 0x1C
274 	"cr13", // 0x1D
275 	"cr14", // 0x1E
276 	"cr15", // 0x1F
277 
278 	// Debug
279 	"dr0", // 0x30
280 	"dr1", // 0x31
281 	"dr2", // 0x32
282 	"dr3", // 0x33
283 	"dr4", // 0x34
284 	"dr5", // 0x35
285 	"dr6", // 0x36
286 	"dr7", // 0x37
287 	"dr8", // 0x38
288 	"dr9", // 0x39
289 	"dr10", // 0x3A
290 	"dr11", // 0x3B
291 	"dr12", // 0x3C
292 	"dr13", // 0x3D
293 	"dr14", // 0x3E
294 	"dr15", // 0x3F
295 
296 	// FPU
297 	"st(0)", // 0x40
298 	"st(1)", // 0x41
299 	"st(2)", // 0x42
300 	"st(3)", // 0x43
301 	"st(4)", // 0x44
302 	"st(5)", // 0x45
303 	"st(6)", // 0x46
304 	"st(7)", // 0x47
305 	NULL, // 0x48
306 	NULL, // 0x49
307 	NULL, // 0x4A
308 	NULL, // 0x4B
309 	NULL, // 0x4C
310 	NULL, // 0x4D
311 	NULL, // 0x4E
312 	NULL, // 0x4F
313 
314 	// MMX
315 	"mm0", // 0x50
316 	"mm1", //
317 	"mm2",
318 	"mm3",
319 	"mm4",
320 	"mm5",
321 	"mm6",
322 	"mm7",
323 	NULL, // 0x58
324 	NULL, // 0x59
325 	NULL, // 0x5A
326 	NULL, // 0x5B
327 	NULL, // 0x5C
328 	NULL, // 0x5D
329 	NULL, // 0x5E
330 	NULL, // 0x5F
331 
332 	// XMM
333 	"xmm0", // 0x60
334 	"xmm1", // 0x61
335 	"xmm2", // 0x62
336 	"xmm3", // 0x63
337 	"xmm4", // 0x64
338 	"xmm5", // 0x65
339 	"xmm6", // 0x66
340 	"xmm7", // 0x67
341 	"xmm8", // 0x68
342 	"xmm9", // 0x69
343 	"xmm10", // 0x6a
344 	"xmm11", // 0x6b
345 	"xmm12", // 0x6c
346 	"xmm13", // 0x6d
347 	"xmm14", // 0x6e
348 	"xmm15", // 0x6f
349 
350 	// 8-bit
351 	"al", // 0x70
352 	"cl", // 0x71
353 	"dl", // 0x72
354 	"bl", // 0x73
355 	"ah", // 0x74
356 	"ch", // 0x75
357 	"dh", // 0x76
358 	"bh", // 0x77
359  	NULL, // 0x78
360 	NULL, // 0x79
361 	NULL, // 0x7A
362 	NULL, // 0x7B
363 	NULL, // 0x7C
364 	NULL, // 0x7D
365 	NULL, // 0x7E
366 	NULL, // 0x7F
367 
368 	// 16-bit
369 	"ax", // 0x80
370 	"cx", // 0x81
371 	"dx", // 0x82
372 	"bx", // 0x83
373 	"sp", // 0x84
374 	"bp", // 0x85
375 	"si", // 0x86
376 	"di", // 0x87
377 	NULL, // 0x88
378 	NULL, // 0x89
379 	NULL, // 0x8A
380 	NULL, // 0x8B
381 	NULL, // 0x8C
382 	NULL, // 0x8D
383 	NULL, // 0x8E
384 	NULL, // 0x8F
385 
386 	// 32-bit
387 	"eax", // 0x90
388 	"ecx", // 0x91
389 	"edx", // 0x92
390 	"ebx", // 0x93
391 	"esp", // 0x94
392 	"ebp", // 0x95
393 	"esi", // 0x96
394 	"edi", // 0x97
395 	NULL, // 0x98
396 	NULL, // 0x99
397 	NULL, // 0x9A
398 	NULL, // 0x9B
399 	NULL, // 0x9C
400 	NULL, // 0x9D
401 	NULL, // 0x9E
402 	NULL, // 0x9F
403 
404 	// X86-64 8-bit register
405 	"al", // 0xA0
406 	"cl", // 0xA1
407 	"dl", // 0xA2
408 	"bl", // 0xA3
409 	"spl", // 0xA4
410 	"bpl", // 0xA5
411 	"sil", // 0xA6
412 	"dil", // 0xA7
413 	"r8b", // 0xA8
414 	"r9b", // 0xA9
415 	"r10b", // 0xAA
416 	"r11b", // 0xAB
417 	"r12b", // 0xAC
418 	"r13b", // 0xAD
419 	"r14b", // 0xAE
420 	"r15b", // 0xAF
421 
422 	// X86-64 16-bit register
423 	"ax", // 0xB0
424 	"cx", // 0xB1
425 	"dx", // 0xB2
426 	"bx", // 0xB3
427 	"sp", // 0xB4
428 	"bp", // 0xB5
429 	"si", // 0xB6
430 	"di", // 0xB7
431 	"r8w", // 0xB8
432 	"r9w", // 0xB9
433 	"r10w", // 0xBA
434 	"r11w", // 0xBB
435 	"r12w", // 0xBC
436 	"r13w", // 0xBD
437 	"r14w", // 0xBE
438 	"r15w", // 0xBF
439 
440 	// X86-64 32-bit register
441 	"eax", // 0xC0
442 	"ecx", // 0xC1
443 	"edx", // 0xC2
444 	"ebx", // 0xC3
445 	"esp", // 0xC4
446 	"ebp", // 0xC5
447 	"esi", // 0xC6
448 	"edi", // 0xC7
449 	"r8d", // 0xC8
450 	"r9d", // 0xC9
451 	"r10d", // 0xCA
452 	"r11d", // 0xCB
453 	"r12d", // 0xCC
454 	"r13d", // 0xCD
455 	"r14d", // 0xCE
456 	"r15d", // 0xCF
457 
458 	// X86-64 64-bit register
459 	"rax", // 0xD0
460 	"rcx", // 0xD1
461 	"rdx", // 0xD2
462 	"rbx", // 0xD3
463 	"rsp", // 0xD4
464 	"rbp", // 0xD5
465 	"rsi", // 0xD6
466 	"rdi", // 0xD7
467 	"r8", // 0xD8
468 	"r9", // 0xD9
469 	"r10", // 0xDA
470 	"r11", // 0xDB
471 	"r12", // 0xDC
472 	"r13", // 0xDD
473 	"r14", // 0xDE
474 	"r15" // 0xDF
475 };
476 
477 void OutputBounds(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
478 void OutputGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
479 void OutputDescriptor(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
480 void OutputSegOffset(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
481 void OutputPackedReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
482 void OutputPackedBCD(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
483 void OutputScalarReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
484 void OutputScalarGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
485 void OutputFPUEnvironment(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
486 void OutputFPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
487 void OutputCPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
488 
489 typedef void (*OUTPUT_OPTYPE)(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
490 #define OPTYPE_SHIFT 24
491 #define MAX_OPTYPE_INDEX 26
492 OUTPUT_OPTYPE OptypeHandlers[] =
493 {
494 	NULL,
495 	OutputBounds,         // 01 OPTYPE_a
496 	OutputGeneral,        // 02 OPTYPE_b
497 	OutputGeneral,        // 03 OPTYPE_d
498 	OutputSegOffset,      // 04 OPTYPE_p
499 	OutputGeneral,        // 05 OPTYPE_q
500 	OutputDescriptor,     // 06 OPTYPE_dt
501 	OutputGeneral,        // 07 OPTYPE_v
502 	OutputGeneral,        // 08 OPTYPE_w
503 	OutputPackedReal,     // 09 OPTYPE_ps
504 	OutputPackedReal,     // 0A OPTYPE_pd
505 	OutputPackedBCD,      // 0B OPTYPE_pb
506 	OutputScalarReal,     // 0C OPTYPE_ss
507 	OutputScalarReal,     // 0D OPTYPE_sd
508 	OutputScalarReal,     // 0E OPTYPE_se
509 	OutputFPUEnvironment, // 0F OPTYPE_fev
510 	OutputFPUState,       // 10 OPTYPE_fst1
511 	OutputFPUState,       // 11 OPTYPE_fst2
512 	OutputGeneral,        // 12 OPTYPE_z
513 	OutputGeneral,        // 13 OPTYPE_o
514 	OutputGeneral,        // 14 OPTYPE_dq
515 	OutputGeneral,        // 15 OPTYPE_mw
516 	OutputScalarGeneral,  // 16 OPTYPE_sso
517 	OutputScalarGeneral,  // 17 OPTYPE_sdo
518 	OutputCPUState,       // 18 OPTYPE_cpu
519 	OutputGeneral,        // 19 OPTYPE_lea
520 };
521 
522 #define OPTYPE_a    0x01000000
523 #define OPTYPE_b    0x02000000
524 #define OPTYPE_d    0x03000000
525 #define OPTYPE_p    0x04000000
526 #define OPTYPE_q    0x05000000
527 #define OPTYPE_dt   0x06000000
528 #define OPTYPE_v    0x07000000
529 #define OPTYPE_w    0x08000000
530 #define OPTYPE_ps   0x09000000 // packed 128-bit single real
531 #define OPTYPE_pd   0x0A000000 // packed 128-bit double real
532 #define OPTYPE_pb	  0x0B000000 // packed BCD (10 bytes, 18-bit precision)
533 #define OPTYPE_ss   0x0C000000 // scalar single real
534 #define OPTYPE_sd   0x0D000000 // scalar double real
535 #define OPTYPE_se   0x0E000000 // scalar extended real
536 #define OPTYPE_fev  0x0F000000 // FPU environment (28 bytes if 32-bit modes, 14 bytes in 16-bit mode)
537 #define OPTYPE_fst1 0x10000000 // FPU state (108 bytes in 32-bit modes, 94 bytes in 16-bit real mode)
538 #define OPTYPE_fst2 0x11000000 // FPU/MMX/XMM/MXCSR state (512 bytes)
539 #define OPTYPE_z	  0x12000000
540 #define OPTYPE_o	  0x13000000
541 #define OPTYPE_dq   0x14000000 // OPTYPE_d or OPTYPE_o
542 #define OPTYPE_mw   0x15000000 // word if memory, register size otherwise
543 #define OPTYPE_sso  0x16000000 // OPTYPE_ss or OPTYPE_o
544 #define OPTYPE_sdo  0x17000000 // OPTYPE_ss or OPTYPE_o
545 #define OPTYPE_cpu  0x18000000 // pointer to CPU state structure
546 #define OPTYPE_lea  0x19000000 // size set by other operand
547 
548 ////////////////////////////////////////////////////////////////////////
549 // Internal functions
550 ////////////////////////////////////////////////////////////////////////
551 
552 #ifdef TEST_DISASM // TODO: remove
553 U32 X86_GetLength(INSTRUCTION *Instruction, U8 *Address);
554 #endif
555 
556 INTERNAL BOOL IsValidLockPrefix(X86_INSTRUCTION *Instruction, U8 Opcode, U32 OpcodeLength, U8 Group, U8 OpcodeExtension);
557 INTERNAL U8 *SetOperands(INSTRUCTION *Instruction, U8 *Address, U32 Flags);
558 INTERNAL U8 *SetModRM32(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors);
559 INTERNAL U8 *SetModRM16(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors);
560 INTERNAL U8 *SetSIB(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors);
561 INTERNAL U64 ApplyDisplacement(U64 Address, INSTRUCTION *Instruction);
562 
563 //////////////////////////////////////////////////////////
564 // Instruction setup
565 //////////////////////////////////////////////////////////
566 
567 #define APPLY_OFFSET(addr) \
568 { \
569 	switch (X86Instruction->OperandSize) \
570 	{ \
571 		case 8: addr = ((U64)(addr + Instruction->VirtualAddressDelta)); break; \
572 		case 4: addr = (U64)((U32)(addr + Instruction->VirtualAddressDelta)); break; \
573 		case 2: addr = (U64)((U8)(addr + Instruction->VirtualAddressDelta)); break; \
574 		default: assert(0); break; \
575 	} \
576 }
577 
X86_InitInstruction(INSTRUCTION * Instruction)578 BOOL X86_InitInstruction(INSTRUCTION *Instruction)
579 {
580 	X86_INSTRUCTION *X86Instruction;
581 #ifdef NO_SANITY_CHECKS
582 	assert(0); // be sure assertions are disabled
583 #endif
584 	X86Instruction = &Instruction->X86;
585 	memset(X86Instruction, 0, sizeof(X86_INSTRUCTION));
586 
587 	switch (INS_ARCH_TYPE(Instruction))
588 	{
589 		case ARCH_X64:
590 			X86Instruction->AddressSize = 8;
591 			X86Instruction->OperandSize = 4;
592 			break;
593 		case ARCH_X86:
594 			X86Instruction->AddressSize = 4;
595 			X86Instruction->OperandSize = 4;
596 			break;
597 		case ARCH_X86_16:
598 			X86Instruction->AddressSize = 2;
599 			X86Instruction->OperandSize = 2;
600 			break;
601 		default:
602 			assert(0);
603 			return FALSE;
604 	}
605 	X86Instruction->Instruction = Instruction;
606 	X86Instruction->Segment = SEG_DS;
607 	return TRUE;
608 }
609 
610 ////////////////////////////////////////////////////////////
611 // Formatting
612 // You can change these to whatever you prefer
613 ////////////////////////////////////////////////////////////
614 
615 #define X86_WRITE_OPFLAGS() \
616 	if (Flags & DISASM_SHOWFLAGS) \
617 	{ \
618 		APPENDB('{'); \
619 		assert(Operand->Flags & (OP_EXEC|OP_SRC|OP_DST)); \
620 		if (Operand->Flags & OP_IPREL) APPENDB('r'); \
621 		if (Operand->Flags & OP_FAR) APPENDB('f'); \
622 		if (Operand->Flags & OP_CONDR) APPENDB('c'); \
623 		if (Operand->Flags & OP_EXEC) APPENDB('X'); \
624 		else if (Operand->Flags & OP_SRC) APPENDB('R'); \
625 		if (Operand->Flags & OP_CONDW) APPENDB('c'); \
626 		if (Operand->Flags & OP_DST) APPENDB('W'); \
627 		if (Operand->Flags & OP_SYS) APPENDB('S'); \
628 		if (Operand->Flags & OP_ADDRESS) APPENDB('A'); \
629 		if (Operand->Flags & OP_PARAM) APPENDB('P'); \
630 		if (Operand->Flags & OP_LOCAL) APPENDB('L'); \
631 		if (Operand->Flags & OP_GLOBAL) APPENDB('G'); \
632 		APPENDB('}'); \
633 	}
634 
635 #define X86_WRITE_IMMEDIATE() \
636 { \
637 	switch (Operand->Length) \
638 	{ \
639 		case 8: \
640 			APPEND(OPCSTR, SIZE_LEFT, "0x%02I64X=", Operand->Value_U64); \
641 			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%I64u", Operand->Value_U64); \
642 			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02I64X=%I64d", -Operand->Value_S64, Operand->Value_S64);*/ \
643 			else APPEND(OPCSTR, SIZE_LEFT, "%I64d", Operand->Value_S64); \
644 			break; \
645 		case 4: \
646 			APPEND(OPCSTR, SIZE_LEFT, "0x%02lX=", (U32)Operand->Value_U64); \
647 			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%lu", (U32)Operand->Value_U64); \
648 			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02lX=%ld", (U32)-Operand->Value_S64, (S32)Operand->Value_S64);*/ \
649 			else APPEND(OPCSTR, SIZE_LEFT, "%ld", (S32)Operand->Value_S64); \
650 			break; \
651 		case 2: \
652 			APPEND(OPCSTR, SIZE_LEFT, "0x%02X=", (U16)Operand->Value_U64); \
653 			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%u", (U16)Operand->Value_U64); \
654 			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02X=%d", (U16)-Operand->Value_S64, (S16)Operand->Value_S64);*/ \
655 			else APPEND(OPCSTR, SIZE_LEFT, "%d", (S16)Operand->Value_S64); \
656 			break; \
657 		case 1: \
658 			APPEND(OPCSTR, SIZE_LEFT, "0x%02X=", (U8)Operand->Value_U64); \
659 			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%u", (U8)Operand->Value_U64); \
660 			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02X=%d", (U8)-Operand->Value_S64, (S8)Operand->Value_S64);*/ \
661 			else APPEND(OPCSTR, SIZE_LEFT, "%d", (S8)Operand->Value_S64); \
662 			break; \
663 		default: assert(0); break; \
664 	} \
665 }
666 
667 #define X86_WRITE_ABSOLUTE_DISPLACEMENT() \
668 {  \
669 	switch (X86Instruction->AddressSize) \
670 	{ \
671 		case 8: \
672 			APPEND(OPCSTR, SIZE_LEFT, "0x%04I64X", X86Instruction->Displacement); \
673 			break; \
674 		case 4: \
675 			APPEND(OPCSTR, SIZE_LEFT, "0x%04lX", (U32)X86Instruction->Displacement); \
676 			break; \
677 		case 2: \
678 			APPEND(OPCSTR, SIZE_LEFT, "0x%04X", (U16)X86Instruction->Displacement); \
679 			break; \
680 		default: assert(0); break; \
681 	} \
682 }
683 
684 #define X86_WRITE_RELATIVE_DISPLACEMENT64() \
685 	if (X86Instruction->Displacement >= 0) APPEND(OPCSTR, SIZE_LEFT, "+0x%02I64X", X86Instruction->Displacement); \
686 	else APPEND(OPCSTR, SIZE_LEFT, "-0x%02I64X", -X86Instruction->Displacement);
687 
688 #define X86_WRITE_RELATIVE_DISPLACEMENT32() \
689 	if (X86Instruction->Displacement >= 0) APPEND(OPCSTR, SIZE_LEFT, "+0x%02lX", (U32)X86Instruction->Displacement); \
690 	else APPEND(OPCSTR, SIZE_LEFT, "-0x%02lX", (U32)-X86Instruction->Displacement);
691 
692 #define X86_WRITE_RELATIVE_DISPLACEMENT16() \
693 	if (X86Instruction->Displacement >= 0) APPEND(OPCSTR, SIZE_LEFT, "+0x%02X", (U16)X86Instruction->Displacement); \
694 	else APPEND(OPCSTR, SIZE_LEFT, "-0x%02X", (U16)-X86Instruction->Displacement);
695 
696 #define X86_WRITE_RELATIVE_DISPLACEMENT() \
697 {  \
698 	switch (X86Instruction->AddressSize) \
699 	{ \
700 		case 8: \
701 			X86_WRITE_RELATIVE_DISPLACEMENT64() \
702 			break; \
703 		case 4: \
704 			X86_WRITE_RELATIVE_DISPLACEMENT32() \
705 			break; \
706 		case 2: \
707 			X86_WRITE_RELATIVE_DISPLACEMENT16() \
708 			break; \
709 		default: assert(0); break; \
710 	} \
711 }
712 
713 #define X86_WRITE_IP_OFFSET(op) \
714 { \
715 	switch (X86Instruction->OperandSize) \
716 	{ \
717 		case 8: \
718 			APPENDS("[rip+ilen"); \
719 			assert((op)->TargetAddress); \
720 			X86_WRITE_RELATIVE_DISPLACEMENT64() \
721 			APPEND(OPCSTR, SIZE_LEFT, "]=0x%04I64X", (op)->TargetAddress+Instruction->VirtualAddressDelta); \
722 			break; \
723 		case 4: \
724 			APPENDS("[eip+ilen"); \
725 			assert((op)->TargetAddress); \
726 			X86_WRITE_RELATIVE_DISPLACEMENT32() \
727 			APPEND(OPCSTR, SIZE_LEFT, "]=0x%04lX", (U32)((op)->TargetAddress+Instruction->VirtualAddressDelta)); \
728 			break; \
729 		case 2: \
730 			APPENDS("[ip+ilen"); \
731 			X86_WRITE_RELATIVE_DISPLACEMENT16() \
732 			APPEND(OPCSTR, SIZE_LEFT, "]=0x%04X", (U16)((op)->TargetAddress+Instruction->VirtualAddressDelta)); \
733 			break; \
734 		default: assert(0); break; \
735 	} \
736 }
737 
738 #define X86_WRITE_OFFSET(op) \
739 { \
740 	assert((op)->Length <= 8); \
741 	if (X86Instruction->HasSelector) \
742 	{ \
743 		assert((op)->Flags & OP_FAR); \
744 		APPEND(OPCSTR, SIZE_LEFT, "%s 0x%02lX:[", DataSizes[((op)->Length >> 1)], X86Instruction->Selector); \
745 	} \
746 	else \
747 	{ \
748 		assert(!((op)->Flags & OP_FAR)); \
749 		assert(X86Instruction->Segment < SEG_MAX) ; \
750 		APPEND(OPCSTR, SIZE_LEFT, "%s %s:[", DataSizes[((op)->Length >> 1)], Segments[X86Instruction->Segment]); \
751 	} \
752 	X86_WRITE_ABSOLUTE_DISPLACEMENT() \
753 	APPENDB(']'); \
754 }
755 
OutputAddress(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)756 void OutputAddress(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
757 {
758 	BOOL ShowDisplacement = FALSE;
759 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
760 
761 	assert(!X86Instruction->HasSelector);
762 	assert(X86Instruction->SrcAddressIndex == OperandIndex || X86Instruction->DstAddressIndex == OperandIndex);
763 	if (Operand->Length > 16 || (Operand->Length > 1 && (Operand->Length & 1))) APPEND(OPCSTR, SIZE_LEFT, "%d_byte ptr ", Operand->Length);
764 	else APPEND(OPCSTR, SIZE_LEFT, "%s ", DataSizes[Operand->Length >> 1]);
765 
766 	//
767 	// This attempts to display the address intelligently
768 	// If it has a positive 32-bit displacement, it is shown as seg:Displacement[base+index*scale]
769 	// If it is a negative displacement or 8-bit, it is shown as seg:[base+index*scale+displacement]
770 	//
771 	APPEND(OPCSTR, SIZE_LEFT, "%s:", Segments[X86Instruction->Segment]);
772 	if (X86Instruction->HasBaseRegister)
773 	{
774 		if (X86Instruction->Displacement)
775 		{
776 			if (X86Instruction->HasFullDisplacement) X86_WRITE_ABSOLUTE_DISPLACEMENT()
777 			else ShowDisplacement = TRUE;
778 		}
779 		APPEND(OPCSTR, SIZE_LEFT, "[%s", X86_Registers[X86Instruction->BaseRegister]);
780 		if (X86Instruction->HasIndexRegister)
781 		{
782 			APPEND(OPCSTR, SIZE_LEFT, "+%s", X86_Registers[X86Instruction->IndexRegister]);
783 			if (X86Instruction->Scale > 1) APPEND(OPCSTR, SIZE_LEFT, "*%d", X86Instruction->Scale);
784 		}
785 		if (ShowDisplacement) X86_WRITE_RELATIVE_DISPLACEMENT()
786 		APPENDB(']');
787 		if (X86Instruction->Relative)
788 		{
789 			U64 Address = Operand->TargetAddress;
790 			assert(Address);
791 			APPLY_OFFSET(Address)
792 			APPEND(OPCSTR, SIZE_LEFT, "=[0x%04I64X]", Address);
793 		}
794 	}
795 	else if (X86Instruction->HasIndexRegister)
796 	{
797 		if (X86Instruction->Displacement)
798 		{
799 			if (X86Instruction->HasFullDisplacement) X86_WRITE_ABSOLUTE_DISPLACEMENT()
800 			else ShowDisplacement = TRUE;
801 		}
802 		APPEND(OPCSTR, SIZE_LEFT, "[%s", X86_Registers[X86Instruction->IndexRegister]);
803 		if (X86Instruction->Scale > 1) APPEND(OPCSTR, SIZE_LEFT, "*%d", X86Instruction->Scale);
804 		if (ShowDisplacement) X86_WRITE_RELATIVE_DISPLACEMENT()
805 		APPENDB(']');
806 	}
807 	else // just a displacement
808 	{
809 		APPENDB('[');
810 		X86_WRITE_ABSOLUTE_DISPLACEMENT()
811 		APPENDB(']');
812 	}
813 }
814 
OutputBounds(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)815 void OutputBounds(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
816 {
817 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
818 	assert(X86Instruction->HasSrcAddressing);
819 	assert(!(Operand->Length & 1));
820 	Operand->Length >>= 1;
821 	APPENDB('(');
822 	OutputAddress(Instruction, Operand, OperandIndex);
823 	APPENDS(", ");
824 	X86Instruction->Displacement += Operand->Length;
825 	OutputAddress(Instruction, Operand, OperandIndex);
826 	X86Instruction->Displacement -= Operand->Length;
827 	APPENDB(')');
828 	Operand->Length <<= 1;
829 }
830 
OutputGeneral(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)831 void OutputGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
832 {
833 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
834 	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
835 		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
836 	{
837 		OutputAddress(Instruction, Operand, OperandIndex);
838 	}
839 	else
840 	{
841 		APPENDS(X86_Registers[Operand->Register]);
842 	}
843 }
844 
OutputDescriptor(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)845 void OutputDescriptor(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
846 {
847 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
848 	assert(X86Instruction->HasSrcAddressing || X86Instruction->HasDstAddressing);
849 	OutputAddress(Instruction, Operand, OperandIndex);
850 }
851 
OutputPackedReal(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)852 void OutputPackedReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
853 {
854 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
855 	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
856 		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
857 	{
858 		OutputAddress(Instruction, Operand, OperandIndex);
859 	}
860 	else
861 	{
862 		APPENDS(X86_Registers[Operand->Register]);
863 	}
864 }
865 
OutputPackedBCD(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)866 void OutputPackedBCD(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
867 {
868 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
869 	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
870 		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
871 	{
872 		OutputAddress(Instruction, Operand, OperandIndex);
873 	}
874 	else
875 	{
876 		APPENDS(X86_Registers[Operand->Register]);
877 	}
878 }
879 
OutputScalarReal(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)880 void OutputScalarReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
881 {
882 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
883 	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
884 		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
885 	{
886 		OutputAddress(Instruction, Operand, OperandIndex);
887 	}
888 	else
889 	{
890 		APPENDS(X86_Registers[Operand->Register]);
891 	}
892 }
893 
OutputScalarGeneral(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)894 void OutputScalarGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
895 {
896 	if (Operand->Type == OPTYPE_FLOAT)
897 	{
898 		OutputScalarReal(Instruction, Operand, OperandIndex);
899 	}
900 	else
901 	{
902 		OutputGeneral(Instruction, Operand, OperandIndex);
903 	}
904 }
905 
OutputFPUEnvironment(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)906 void OutputFPUEnvironment(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
907 {
908 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
909 	assert(X86Instruction->HasSrcAddressing || X86Instruction->HasDstAddressing);
910 	OutputAddress(Instruction, Operand, OperandIndex);
911 }
912 
OutputFPUState(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)913 void OutputFPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
914 {
915 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
916 	assert(X86Instruction->HasSrcAddressing || X86Instruction->HasDstAddressing);
917 	OutputAddress(Instruction, Operand, OperandIndex);
918 }
919 
OutputCPUState(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)920 void OutputCPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
921 {
922 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
923 	assert(X86Instruction->HasSrcAddressing);
924 	OutputAddress(Instruction, Operand, OperandIndex);
925 }
926 
OutputSegOffset(INSTRUCTION * Instruction,INSTRUCTION_OPERAND * Operand,U32 OperandIndex)927 void OutputSegOffset(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
928 {
929 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
930 	assert(X86Instruction->HasSrcAddressing);
931 	OutputAddress(Instruction, Operand, OperandIndex);
932 }
933 
934 ////////////////////////////////////////////////////////////
935 // Prologue support
936 ////////////////////////////////////////////////////////////
937 
938 typedef struct _PROLOGUE
939 {
940 	char *Data;
941 	U32 Length;
942 } PROLOGUE;
943 
944 PROLOGUE StandardPrologues[] =
945 {
946 	{ "\x55\x8b\xec", 3 },
947 	{ "\x55\x89\xe5", 3 },
948 	{ "\x83\xec", 2 },
949 	{ "\x81\xec", 2 },
950 	// TODO: add AMD64 prologues
951 	// TODO: add VS2003/VS2003 prologues
952 	// TODO: add any unique prologues from other compilers
953 	{ NULL, 0 }
954 };
955 
956 // Find the first function between StartAddress and EndAddress
957 //
958 // This will match a standard prologue and then analyze the following instructions to verify
959 // it is a valid function
X86_FindFunctionByPrologue(INSTRUCTION * Instruction,U8 * StartAddress,U8 * EndAddress,U32 Flags)960 U8 *X86_FindFunctionByPrologue(INSTRUCTION *Instruction, U8 *StartAddress, U8 *EndAddress, U32 Flags)
961 {
962 	assert(0); // TODO
963 	return NULL;
964 }
965 
966 //////////////////////////////////////////////////////////
967 // Instruction decoder
968 //////////////////////////////////////////////////////////
969 
X86_GetInstruction(INSTRUCTION * Instruction,U8 * Address,U32 Flags)970 BOOL X86_GetInstruction(INSTRUCTION *Instruction, U8 *Address, U32 Flags)
971 {
972 	BOOL SpecialExtension = FALSE;
973 	U8 Opcode = 0, OpcodeExtension = 0, Group = 0, SSE_Prefix = 0, Suffix;
974 	U32 i = 0, Result = 0, tmpScale;
975 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
976 	X86_OPCODE *X86Opcode;
977 #ifdef TEST_DISASM
978 	U32 InstructionLength = 0;
979 #endif
980 	INSTRUCTION_OPERAND *Operand, *Operand1 = NULL;
981 	DISASSEMBLER *Disassembler = Instruction->Disassembler;
982 	BOOL Decode = Flags & DISASM_DECODE;
983 	BOOL Disassemble = Flags & DISASM_DISASSEMBLE;
984 	BOOL SuppressErrors = Flags & DISASM_SUPPRESSERRORS;
985 
986 	if (Disassemble && !Decode)
987 	{
988 		assert(0);
989 		Decode = TRUE;
990 	}
991 
992 	if (!Address || !X86_InitInstruction(Instruction))
993 	{
994 		assert(0);
995 		goto abort;
996 	}
997 
998 	assert(Instruction->Address == Address);
999 	assert(!Instruction->StringIndex && !Instruction->Length);
1000 
1001 	Disassembler->Stage1Count++;
1002 	if (Flags & DISASM_ALIGNOUTPUT) Instruction->StringAligned = TRUE;
1003 
1004 	//
1005 	// Get prefixes or three byte opcode
1006 	//
1007 	while (TRUE)
1008 	{
1009 		Opcode = *Address;
1010 		INSTR_INC(1); // increment Instruction->Length and address
1011 		X86Opcode = &X86_Opcodes_1[Opcode];
1012 
1013 		// Handle a misplaced REX prefix -- AMD64 manual says it is just ignored
1014 		if (IS_AMD64() && (Opcode >= REX_PREFIX_START && Opcode <= REX_PREFIX_END) && X86_PREFIX((&X86_Opcodes_1[*Address])))
1015 		{
1016 			if (!Instruction->AnomalyOccurred)
1017 			{
1018 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: REX prefix before legacy prefix 0x%02X\n", VIRTUAL_ADDRESS, Opcode);
1019 				Instruction->AnomalyOccurred = TRUE;
1020 			}
1021 			continue;
1022 		}
1023 
1024 		if (X86_PREFIX(X86Opcode))
1025 		{
1026 			if (!Instruction->AnomalyOccurred)
1027 			{
1028 				for (i = 0; i < Instruction->PrefixCount; i++)
1029 				{
1030 					if (Instruction->Prefixes[i] == Opcode)
1031 					{
1032 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Duplicate prefix 0x%02X\n", VIRTUAL_ADDRESS, Opcode);
1033 						Instruction->AnomalyOccurred = TRUE;
1034 						break;
1035 					}
1036 				}
1037 			}
1038 
1039 			switch (Opcode)
1040 			{
1041 				case PREFIX_REPNE: // may be three byte opcode
1042 					SSE_Prefix = Opcode;
1043 					if (!Instruction->AnomalyOccurred && X86Instruction->HasRepeatWhileEqualPrefix)
1044 					{
1045 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
1046 						Instruction->AnomalyOccurred = TRUE;
1047 					}
1048 					Instruction->Repeat = TRUE;
1049 					X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
1050 					X86Instruction->HasRepeatWhileNotEqualPrefix = TRUE;
1051 					break;
1052 				case PREFIX_REP: // may be three byte opcode
1053 					SSE_Prefix = Opcode;
1054 					if (!Instruction->AnomalyOccurred && X86Instruction->HasRepeatWhileNotEqualPrefix)
1055 					{
1056 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
1057 						Instruction->AnomalyOccurred = TRUE;
1058 					}
1059 
1060 					Instruction->Repeat = TRUE;
1061 					X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
1062 					X86Instruction->HasRepeatWhileEqualPrefix = TRUE;
1063 					break;
1064 
1065 				case PREFIX_OPERAND_SIZE: // may be three byte opcode
1066 					SSE_Prefix = Opcode;
1067 					if (!Instruction->AnomalyOccurred && X86Instruction->HasOperandSizePrefix)
1068 					{
1069 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
1070 						Instruction->AnomalyOccurred = TRUE;
1071 					}
1072 
1073 					if (X86Instruction->HasOperandSizePrefix) break;
1074 					else X86Instruction->HasOperandSizePrefix = TRUE;
1075 					switch (X86Instruction->OperandSize)
1076 					{
1077 						case 4: X86Instruction->OperandSize = 2; break;
1078 						case 2: X86Instruction->OperandSize = 4; break;
1079 						default: assert(0); goto abort;
1080 					}
1081 					break;
1082 
1083 				case PREFIX_ADDRESS_SIZE:
1084 					if (!Instruction->AnomalyOccurred && X86Instruction->HasAddressSizePrefix)
1085 					{
1086 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
1087 						Instruction->AnomalyOccurred = TRUE;
1088 					}
1089 
1090 					if (X86Instruction->HasAddressSizePrefix) break;
1091 					else X86Instruction->HasAddressSizePrefix = TRUE;
1092 					switch (X86Instruction->AddressSize)
1093 					{
1094 						case 8:
1095 							X86Instruction->AddressSize = 4;
1096 							break;
1097 						case 4:
1098 							assert(!IS_AMD64()); // this should not be possible
1099 							X86Instruction->AddressSize = 2;
1100 							break;
1101 						case 2:
1102 							X86Instruction->AddressSize = 4;
1103 							break;
1104 						default:
1105 							assert(0); goto abort;
1106 					}
1107 					break;
1108 
1109 				case PREFIX_SEGMENT_OVERRIDE_ES:
1110 					SANITY_CHECK_SEGMENT_OVERRIDE();
1111 					if (!IS_AMD64())
1112 					{
1113 						X86Instruction->HasSegmentOverridePrefix = TRUE;
1114 						X86Instruction->Segment = SEG_ES;
1115 					}
1116 					else if (!Instruction->AnomalyOccurred)
1117 					{
1118 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
1119 						Instruction->AnomalyOccurred = TRUE;
1120 					}
1121 					break;
1122 				case PREFIX_SEGMENT_OVERRIDE_CS:
1123 					SANITY_CHECK_SEGMENT_OVERRIDE();
1124 					if (!IS_AMD64())
1125 					{
1126 						X86Instruction->HasSegmentOverridePrefix = TRUE;
1127 						X86Instruction->Segment = SEG_CS;
1128 					}
1129 					else if (!Instruction->AnomalyOccurred)
1130 					{
1131 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
1132 						Instruction->AnomalyOccurred = TRUE;
1133 					}
1134 					break;
1135 				case PREFIX_SEGMENT_OVERRIDE_SS:
1136 					SANITY_CHECK_SEGMENT_OVERRIDE();
1137 					if (!IS_AMD64())
1138 					{
1139 						X86Instruction->HasSegmentOverridePrefix = TRUE;
1140 						X86Instruction->Segment = SEG_SS;
1141 					}
1142 					else if (!Instruction->AnomalyOccurred)
1143 					{
1144 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
1145 						Instruction->AnomalyOccurred = TRUE;
1146 					}
1147 					break;
1148 				case PREFIX_SEGMENT_OVERRIDE_DS:
1149 					SANITY_CHECK_SEGMENT_OVERRIDE();
1150 					if (!IS_AMD64())
1151 					{
1152 						X86Instruction->HasSegmentOverridePrefix = TRUE;
1153 						X86Instruction->Segment = SEG_DS;
1154 					}
1155 					else if (!Instruction->AnomalyOccurred)
1156 					{
1157 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
1158 						Instruction->AnomalyOccurred = TRUE;
1159 					}
1160 					break;
1161 				case PREFIX_SEGMENT_OVERRIDE_FS:
1162 					SANITY_CHECK_SEGMENT_OVERRIDE();
1163 					X86Instruction->HasSegmentOverridePrefix = TRUE;
1164 					X86Instruction->Segment = SEG_FS;
1165 					break;
1166 				case PREFIX_SEGMENT_OVERRIDE_GS:
1167 					SANITY_CHECK_SEGMENT_OVERRIDE();
1168 					X86Instruction->HasSegmentOverridePrefix = TRUE;
1169 					X86Instruction->Segment = SEG_GS;
1170 					break;
1171 
1172 				case PREFIX_LOCK:
1173 					if (!Instruction->AnomalyOccurred && X86Instruction->HasLockPrefix)
1174 					{
1175 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
1176 						Instruction->AnomalyOccurred = TRUE;
1177 					}
1178 					X86Instruction->HasLockPrefix = TRUE;
1179 					break;
1180 
1181 				default:
1182 					assert(0);
1183 					goto abort;
1184 			}
1185 
1186 			if (Instruction->PrefixCount >= X86_MAX_INSTRUCTION_LEN)
1187 			{
1188 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
1189 				goto abort;
1190 			}
1191 			else if (Instruction->PrefixCount == X86_MAX_PREFIX_LENGTH)
1192 			{
1193 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
1194 				Instruction->AnomalyOccurred = TRUE;
1195 			}
1196 
1197 			assert(Instruction->AnomalyOccurred || Instruction->PrefixCount < X86_MAX_PREFIX_LENGTH);
1198 			Instruction->Prefixes[Instruction->PrefixCount] = Opcode;
1199 			Instruction->PrefixCount++;
1200 			//DISASM_OUTPUT(("[0x%08I64X] Prefix 0x%02X (prefix count %d)\n", VIRTUAL_ADDRESS, Opcode, Instruction->PrefixCount));
1201 		}
1202 		else
1203 		{
1204 			break;
1205 		}
1206 	}
1207 
1208 	// Check for REX opcode
1209 	// This is checked here instead of the prefix loop above because it must be the
1210 	// last prefix
1211 	if (IS_AMD64() && (Opcode >= REX_PREFIX_START && Opcode <= REX_PREFIX_END))
1212 	{
1213 		if (Instruction->PrefixCount >= X86_MAX_INSTRUCTION_LEN)
1214 		{
1215 			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
1216 			goto abort;
1217 		}
1218 		else if (!Instruction->AnomalyOccurred && Instruction->PrefixCount == AMD64_MAX_PREFIX_LENGTH)
1219 		{
1220 			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
1221 			Instruction->AnomalyOccurred = TRUE;
1222 		}
1223 
1224 		assert(Instruction->AnomalyOccurred || Instruction->PrefixCount < AMD64_MAX_PREFIX_LENGTH);
1225 
1226 		Instruction->Prefixes[Instruction->PrefixCount] = Opcode;
1227 		Instruction->PrefixCount++;
1228 		X86Instruction->rex_b = Opcode;
1229 		SET_REX(X86Instruction->rex, X86Instruction->rex_b);
1230 		DISASM_OUTPUT(("[0x%08I64X] REX prefix 0x%02X (prefix count %d, w=%d, r=%d, x=%d, b=%d)\n", VIRTUAL_ADDRESS, Opcode, Instruction->PrefixCount, X86Instruction->rex.w, X86Instruction->rex.r, X86Instruction->rex.x, X86Instruction->rex.b));
1231 
1232 		assert(X86Instruction->AddressSize >= 4);
1233 		if (X86Instruction->rex.w)
1234 		{
1235 			X86Instruction->OperandSize = 8;
1236 			X86Instruction->HasOperandSizePrefix = FALSE;
1237 		}
1238 		else if (X86Instruction->HasOperandSizePrefix)
1239 		{
1240 			assert(X86Instruction->OperandSize == 2);
1241 		}
1242 		else if (X86Instruction->rex_b == REX_PREFIX_START)
1243 		{
1244 			if (!Instruction->AnomalyOccurred)
1245 			{
1246 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: meaningless REX prefix used\n", VIRTUAL_ADDRESS);
1247 				Instruction->AnomalyOccurred = TRUE;
1248 			}
1249 			X86Instruction->rex_b = 0;
1250 		}
1251 
1252 		Opcode = *Address;
1253 		INSTR_INC(1); // increment Instruction->Length and address
1254 
1255 		X86Opcode = &X86_Opcodes_1[Opcode];
1256 		assert(!X86_PREFIX(X86Opcode));
1257 	}
1258 	//DISASM_OUTPUT(("[0x%08I64X] OperandSize = %d, AddressSize = %d\n", VIRTUAL_ADDRESS, X86Instruction->OperandSize, X86Instruction->AddressSize));
1259 	Instruction->LastOpcode = Opcode;
1260 	Instruction->OpcodeAddress = Address-1;
1261 
1262 	if (X86_INVALID(X86Opcode))
1263 	{
1264 		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid opcode 0x%02X\n", VIRTUAL_ADDRESS, Opcode);
1265 		goto abort;
1266 	}
1267 
1268 	if (Opcode == X86_TWO_BYTE_OPCODE)
1269 	{
1270 		//
1271 		// Handle case that it is a group (with opcode extension), floating point, or two byte opcode
1272 		//
1273 		assert(!Instruction->OpcodeLength);
1274 		Instruction->LastOpcode = Opcode = *Address;
1275 		INSTR_INC(1); // increment Instruction->Length and address
1276 		assert(X86Opcode->Table == X86_Opcodes_2);
1277 		X86Opcode = &X86_Opcodes_2[Opcode];
1278 
1279 		//
1280 		// Check for errors
1281 		//
1282 		if (X86_INVALID(X86Opcode))
1283 		{
1284 			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid two byte opcode 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode);
1285 			goto abort;
1286 		}
1287 
1288 		if (X86Instruction->AddressSize == 8)
1289 		{
1290 			if (X86_Invalid_Addr64_2[Opcode])
1291 			{
1292 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X 0x%02X (\"%s\") illegal in 64-bit mode\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, X86Opcode->Mnemonic);
1293 				goto abort;
1294 			}
1295 #if 0
1296 			if (X86Instruction->rex_b &&
1297 					(GET_REX_B(X86Instruction->rex_b) && !GET_REX_B(X86_REX_2[Opcode]) ||
1298 					 GET_REX_X(X86Instruction->rex_b) && !GET_REX_X(X86_REX_2[Opcode]) ||
1299 					 GET_REX_R(X86Instruction->rex_b) && !GET_REX_R(X86_REX_2[Opcode]) ||
1300 					 GET_REX_W(X86Instruction->rex_b) && !GET_REX_W(X86_REX_2[Opcode])))
1301 			{
1302 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal REX prefix 0x%02X for opcode 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86Instruction->rex_b, X86_TWO_BYTE_OPCODE, Opcode);
1303 				assert(0);
1304 				goto abort;
1305 			}
1306 #endif
1307 		}
1308 
1309 		if (X86Instruction->OperandSize == 2 && X86_Invalid_Op16_2[Opcode])
1310 		{
1311 			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X 0x%02X (\"%s\") illegal with 16-bit operand size\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, X86Opcode->Mnemonic);
1312 			goto abort;
1313 		}
1314 
1315 		X86Instruction->HasModRM = X86_ModRM_2[Opcode];
1316 		if (X86Instruction->HasModRM) X86Instruction->modrm_b = *Address;
1317 		Instruction->OpcodeBytes[0] = X86_TWO_BYTE_OPCODE;
1318 		Instruction->OpcodeBytes[1] = Opcode;
1319 		Instruction->OpcodeLength = 2;
1320 
1321 		if (X86_SPECIAL_EXTENSION(X86Opcode))
1322 		{
1323 			DISASM_OUTPUT(("[0x%08I64X] Special opcode extension 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode));
1324 			SpecialExtension = TRUE;
1325 			goto HasSpecialExtension;
1326 		}
1327 		else if (SSE_Prefix && !X86_INVALID(&X86_SSE[Opcode])) // SSEx instruction
1328 		{
1329 			Instruction->OpcodeLength = 3;
1330 			Instruction->OpcodeBytes[2] = SSE_Prefix;
1331 			assert(Instruction->OpcodeBytes[1] == Opcode);
1332 
1333 			// Since the prefix was really an opcode extension, remove it from
1334 			// the prefix list
1335 			for (i = 0; i < Instruction->PrefixCount; i++)
1336 			{
1337 				if (Instruction->Prefixes[i]) break;
1338 			}
1339 			assert(i != Instruction->PrefixCount);
1340 			Instruction->PrefixCount--;
1341 			Instruction->Prefixes[i] = 0;
1342 
1343 			// Slide any prefixes following the removed prefix down by 1
1344 			memmove(&Instruction->Prefixes[i], &Instruction->Prefixes[i+1], Instruction->PrefixCount-i);
1345 			Instruction->Prefixes[Instruction->PrefixCount] = 0;
1346 			Instruction->Repeat = FALSE;
1347 			X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
1348 			X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
1349 			X86Instruction->HasOperandSizePrefix = FALSE;
1350 			if (SSE_Prefix == PREFIX_OPERAND_SIZE)
1351 			{
1352 				if (IS_AMD64() && X86Instruction->rex.w) X86Instruction->OperandSize = 8;
1353 				else X86Instruction->OperandSize = 4;
1354 			}
1355 
1356 			if (IS_X86_16())
1357 			{
1358 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: SSE invalid in 16-bit mode\n", VIRTUAL_ADDRESS);
1359 				goto abort;
1360 			}
1361 
1362 			assert(X86Instruction->HasModRM);
1363 			switch (SSE_Prefix)
1364 			{
1365 				case PREFIX_OPERAND_SIZE: X86Opcode = &X86_SSE[0x000+Opcode]; break;
1366 				case PREFIX_REPNE: X86Opcode = &X86_SSE[0x100+Opcode]; break;
1367 				case PREFIX_REP: X86Opcode = &X86_SSE[0x200+Opcode]; break;
1368 			}
1369 
1370 			if (X86_INVALID(X86Opcode))
1371 			{
1372 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal SSE instruction opcode 0x%02X 0x%02X + prefix 0x%02X\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], Instruction->OpcodeBytes[2]);
1373 				goto abort;
1374 			}
1375 			else if (X86_EXTENDED_OPCODE(X86Opcode))
1376 			{
1377 				// SSE in group (13, 14, or 15)
1378 				OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
1379 				Group = X86_Groups_2[Opcode];
1380 				X86Instruction->Group = (U8)Group;
1381 				assert(Group >= 13 && Group <= 15 && X86Opcode->Table);
1382 				switch (SSE_Prefix)
1383 				{
1384 					case PREFIX_OPERAND_SIZE: X86Opcode = &X86Opcode->Table[0x00+OpcodeExtension]; break;
1385 					case PREFIX_REPNE: X86Opcode = &X86Opcode->Table[0x08+OpcodeExtension]; break;
1386 					case PREFIX_REP: X86Opcode = &X86Opcode->Table[0x10+OpcodeExtension]; break;
1387 				}
1388 
1389 				if (X86_INVALID(X86Opcode))
1390 				{
1391 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal SSE instruction opcode 0x%02X 0x%02X + prefix 0x%02X + extension %d\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], Instruction->OpcodeBytes[2], OpcodeExtension);
1392 					goto abort;
1393 				}
1394 			}
1395 
1396 			Instruction->Repeat = FALSE;
1397 			X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
1398 			X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
1399 			X86Instruction->HasOperandSizePrefix = FALSE;
1400 			switch (X86_GET_CATEGORY(X86Opcode))
1401 			{
1402 				case ITYPE_SSE: case ITYPE_SSE2: case ITYPE_SSE3: break;
1403 				default: assert(0); goto abort;
1404 			}
1405 		}
1406 		else if (X86_EXTENDED_OPCODE(X86Opcode)) // 2 byte group
1407 		{
1408 			assert(!X86Opcode->MnemonicFlags);
1409 			OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
1410 
1411 			assert(X86Opcode->Table);
1412 			X86Opcode = &X86Opcode->Table[OpcodeExtension];
1413 			if (X86_INVALID(X86Opcode))
1414 			{
1415 				Instruction->Length++;
1416 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid group opcode 0x%02X 0x%02X extension 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension);
1417 				goto abort;
1418 			}
1419 
1420 			assert(!X86_SPECIAL_EXTENSION(X86Opcode));
1421 			Group = X86_Groups_2[Opcode];
1422 			X86Instruction->Group = (U8)Group;
1423 			assert(Group > 0 && Group <= 19);
1424 			assert(X86Opcode->Mnemonic);
1425 			DISASM_OUTPUT(("[0x%08I64X] Group %d (bytes 0x%02X 0x%02X) extension 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Group, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension, X86Opcode->Mnemonic));
1426 		}
1427 		else
1428 		{
1429 			assert(X86Opcode->Mnemonic);
1430 			DISASM_OUTPUT(("[0x%08I64X] Two byte opcode 0x%02X 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, X86Opcode->Mnemonic));
1431 			X86Instruction->HasModRM = X86_ModRM_2[Opcode];
1432 			if (X86Instruction->HasModRM) X86Instruction->modrm_b = *Address;
1433 		}
1434 	}
1435 	else // 1-byte opcode
1436 	{
1437 		if (X86Instruction->AddressSize == 8)
1438 		{
1439 			if (X86_Invalid_Addr64_1[Opcode])
1440 			{
1441 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X (\"%s\") illegal in 64-bit mode\n", VIRTUAL_ADDRESS, Opcode, X86Opcode->Mnemonic);
1442 				goto abort;
1443 			}
1444 
1445 #if 0
1446 			if (X86Instruction->rex_b &&
1447 				(GET_REX_B(X86Instruction->rex_b) && !GET_REX_B(X86_REX_1[Opcode]) ||
1448 				 GET_REX_X(X86Instruction->rex_b) && !GET_REX_X(X86_REX_1[Opcode]) ||
1449 				 GET_REX_R(X86Instruction->rex_b) && !GET_REX_R(X86_REX_1[Opcode]) ||
1450 				 GET_REX_W(X86Instruction->rex_b) && !GET_REX_W(X86_REX_1[Opcode])))
1451 			{
1452 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal REX prefix 0x%02X for opcode 0x%02X\n", VIRTUAL_ADDRESS, X86Instruction->rex_b, Opcode);
1453 				assert(0);
1454 				goto abort;
1455 			}
1456 #endif
1457 		}
1458 
1459 		if (X86Instruction->OperandSize == 2 && X86_Invalid_Op16_1[Opcode])
1460 		{
1461 			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X (\"%s\") illegal with 16-bit operand size\n", VIRTUAL_ADDRESS, Opcode, X86Opcode->Mnemonic);
1462 			goto abort;
1463 		}
1464 
1465 		Instruction->OpcodeBytes[0] = Opcode;
1466 		Instruction->OpcodeLength = 1;
1467 		X86Instruction->HasModRM = X86_ModRM_1[Opcode];
1468 		if (X86Instruction->HasModRM) X86Instruction->modrm_b = *Address;
1469 
1470 		if (X86_EXTENDED_OPCODE(X86Opcode)) // a group
1471 		{
1472 			assert(X86Instruction->HasModRM);
1473 			OpcodeExtension = GET_MODRM_EXT(*Address); // leave Address pointing at ModRM byte
1474 
1475 			if (X86_SPECIAL_EXTENSION(X86Opcode))
1476 			{
1477 				DISASM_OUTPUT(("[0x%08I64X] Special opcode extension 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode));
1478 				SpecialExtension = TRUE;
1479 				goto HasSpecialExtension;
1480 			}
1481 
1482 			assert(X86Opcode->Table);
1483 			X86Opcode = &X86Opcode->Table[OpcodeExtension];
1484 			if (X86_INVALID(X86Opcode))
1485 			{
1486 				Instruction->Length++;
1487 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid group opcode 0x%02X extension 0x%02X\n", VIRTUAL_ADDRESS, Opcode, OpcodeExtension);
1488 				goto abort;
1489 			}
1490 
1491 			Group = X86_Groups_1[Opcode];
1492 			X86Instruction->Group = (U8)Group;
1493 			DISASM_OUTPUT(("[0x%08I64X] Group %d (byte 0x%02X) extension 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Group, Opcode, OpcodeExtension, X86Opcode->Mnemonic));
1494 			assert(Group > 0 && Group <= 17);
1495 			assert(X86Opcode->Mnemonic);
1496 		}
1497 		else
1498 		{
1499 			if (X86_SPECIAL_EXTENSION(X86Opcode))
1500 			{
1501 				DISASM_OUTPUT(("[0x%08I64X] Special opcode extension 0x%02X\n", VIRTUAL_ADDRESS, Opcode));
1502 				SpecialExtension = TRUE;
1503 				goto HasSpecialExtension;
1504 			}
1505 
1506 			DISASM_OUTPUT(("[0x%08I64X] One byte opcode 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Opcode, X86Opcode->Mnemonic));
1507 		}
1508 	}
1509 
1510 HasSpecialExtension:
1511 	if (SpecialExtension)
1512 	{
1513 		if (X86Opcode->MnemonicFlags & ITYPE_EXT_MODRM)
1514 		{
1515 			assert(X86Opcode->Table);
1516 			assert(Instruction->OpcodeLength == 2);
1517 			assert(X86Instruction->HasModRM);
1518 			X86Opcode = &X86Opcode->Table[*Address];
1519 			if (X86_INVALID(X86Opcode))
1520 			{
1521 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal opcode 0x%02X 0x%02X + modrm 0x%02X\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], *Address);
1522 				goto abort;
1523 			}
1524 			else if (X86_EXTENDED_OPCODE(X86Opcode))
1525 			{
1526 				assert(!X86Opcode->MnemonicFlags);
1527 				OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
1528 
1529 				assert(X86Opcode->Table);
1530 				X86Opcode = &X86Opcode->Table[OpcodeExtension];
1531 				if (X86_INVALID(X86Opcode))
1532 				{
1533 					Instruction->Length++;
1534 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid group opcode 0x%02X 0x%02X extension 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension);
1535 					goto abort;
1536 				}
1537 
1538 				assert(!X86_SPECIAL_EXTENSION(X86Opcode));
1539 				Group = X86_Groups_2[Opcode];
1540 				X86Instruction->Group = (U8)Group;
1541 				assert(Group > 0 && Group <= 19);
1542 				assert(X86Opcode->Mnemonic);
1543 				DISASM_OUTPUT(("[0x%08I64X] Group %d (bytes 0x%02X 0x%02X) extension 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Group, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension, X86Opcode->Mnemonic));
1544 			}
1545 			else if (!X86_OPERAND_COUNT(X86Opcode))
1546 			{
1547 				INSTR_INC(1); // increment Instruction->Length and address
1548 			}
1549 		}
1550 		else if (X86Opcode->MnemonicFlags & ITYPE_EXT_FPU)
1551 		{
1552 			assert(X86Opcode->Table);
1553 			if (X86Instruction->modrm_b < 0xC0)
1554 			{
1555 				// It is an opcode extension, use the X86Opcode->Table
1556 				OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
1557 				X86Opcode = &X86Opcode->Table[OpcodeExtension];
1558 			}
1559 			else
1560 			{
1561 				// The whole ModRM byte is used, these start at index 0x08 in X86Opcode->Table
1562 				OpcodeExtension = (X86Instruction->modrm_b & 0x3F);
1563 				X86Opcode = &X86Opcode->Table[0x08 + OpcodeExtension];
1564 			}
1565 
1566 			if (X86_INVALID(X86Opcode))
1567 			{
1568 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid FPU opcode 0x%02X + modrm extension 0x%02X (index 0x%02X)\n", VIRTUAL_ADDRESS, Opcode, X86Instruction->modrm_b, 0x08 + OpcodeExtension);
1569 				goto abort;
1570 			}
1571 
1572 			DISASM_OUTPUT(("[0x%08I64X] FPU instruction is (\"%s\"): 0x%02X + modrm 0x%02X (index 0x%02X)\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Opcode, X86Instruction->modrm_b, 0x08 + OpcodeExtension));
1573 			if (!X86_OPERAND_COUNT(X86Opcode)) INSTR_INC(1); // increment Instruction->Length and address
1574 		}
1575 		else if (X86Opcode->MnemonicFlags & ITYPE_EXT_SUFFIX)
1576 		{
1577 			if (X86Instruction->HasOperandSizePrefix)
1578 			{
1579 				if (!Instruction->AnomalyOccurred && X86Opcode->Table == X86_3DNOW_0F)
1580 				{
1581 					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: operand size prefix used with 3DNOW instruction\n", VIRTUAL_ADDRESS);
1582 					Instruction->AnomalyOccurred = TRUE;
1583 				}
1584 				X86Instruction->HasOperandSizePrefix = FALSE;
1585 				X86Instruction->OperandSize = 4;
1586 			}
1587 			Instruction->OperandCount = X86_OPERAND_COUNT(X86Opcode);
1588 			assert(Instruction->OpcodeLength == 2 && X86Instruction->HasModRM && Instruction->OperandCount == 2);
1589 			memcpy(&X86Instruction->Opcode, X86Opcode, sizeof(X86_OPCODE));
1590 			Instruction->Operands[0].Flags = X86Opcode->OperandFlags[0] & X86_OPFLAGS_MASK;
1591 			Instruction->Operands[1].Flags = X86Opcode->OperandFlags[1] & X86_OPFLAGS_MASK;
1592 			Instruction->Operands[2].Flags = X86Opcode->OperandFlags[2] & X86_OPFLAGS_MASK;
1593 			assert(Address == Instruction->Address + Instruction->Length);
1594 			if (!SetOperands(Instruction, Address, Flags & DISASM_SUPPRESSERRORS)) goto abort;
1595 			Suffix = Instruction->Address[Instruction->Length++];
1596 			Instruction->OpcodeBytes[2] = Suffix;
1597 			Instruction->OpcodeLength = 3;
1598 			X86Opcode = &X86Opcode->Table[Suffix];
1599 
1600 			if (X86_INVALID(X86Opcode))
1601 			{
1602 				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal opcode 0x%02X 0x%02X + suffix 0x%02X\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], Suffix);
1603 				goto abort;
1604 			}
1605 			assert(Instruction->Length >= 4 + Instruction->PrefixCount);
1606 		}
1607 		else if (X86Opcode->MnemonicFlags & ITYPE_EXT_64)
1608 		{
1609 			assert(X86Opcode->Table);
1610 			if (IS_AMD64()) X86Opcode = &X86Opcode->Table[1];
1611 			else X86Opcode = &X86Opcode->Table[0];
1612 			assert(!X86_INVALID(X86Opcode));
1613 		}
1614 	}
1615 
1616 	// Detect incompatibilities
1617 	if (IS_X86_16() && X86Opcode->CPU > CPU_I386)
1618 	{
1619 		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Instruction \"%s\" (opcode 0x%02X) can't be used in 16-bit X86\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Instruction->LastOpcode);
1620 		goto abort;
1621 	}
1622 	if (!IS_AMD64() && X86Opcode->CPU >= CPU_AMD64)
1623 	{
1624 		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Instruction \"%s\" (opcode 0x%02X) can only be used in X86-64\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Instruction->LastOpcode);
1625 		goto abort;
1626 	}
1627 
1628 	// Copy the opcode into the local structure and set the fields
1629 	assert(Instruction->OpcodeLength && !X86_INVALID(X86Opcode));
1630 	memcpy(&X86Instruction->Opcode, X86Opcode, sizeof(X86_OPCODE));
1631 	Instruction->Groups |= X86_GET_CATEGORY(X86Opcode);
1632 	assert(Instruction->Groups);
1633 	Instruction->Type |= X86_GET_TYPE(X86Opcode);
1634 	assert((U32)Instruction->Type >= Instruction->Groups);
1635 	Instruction->OperandCount = X86_OPERAND_COUNT(X86Opcode);
1636 
1637 	//
1638 	// Sanity check prefixes now that opcode is known and prefixes are resolved
1639 	//
1640 
1641 	// Instructions that implicitly reference the CS/DS can't have segment override prefixes
1642 	switch (Instruction->Type)
1643 	{
1644 		case ITYPE_PUSHF: case ITYPE_POPF:
1645 		case ITYPE_ENTER: case ITYPE_LEAVE:
1646 			SANITY_CHECK_SEGMENT_OVERRIDE();
1647 			X86Instruction->HasSegmentOverridePrefix = FALSE;
1648 			X86Instruction->Segment = SEG_SS;
1649 			break;
1650 		case ITYPE_RET: case ITYPE_DEBUG:
1651 		case ITYPE_OFLOW: case ITYPE_TRAP:
1652 		case ITYPE_TRAPRET:
1653 			SANITY_CHECK_SEGMENT_OVERRIDE();
1654 			X86Instruction->HasSegmentOverridePrefix = FALSE;
1655 			X86Instruction->Segment = SEG_CS;
1656 			break;
1657 	}
1658 
1659 	// Check illegal prefixes used with FPU/MMX/SSEx
1660 	if (Instruction->Groups & (ITYPE_FPU|ITYPE_MMX|ITYPE_SSE|ITYPE_SSE2|ITYPE_SSE3))
1661 	{
1662 		// Check for prefixes that produce unpredictable results
1663 		for (i = 0; i < Instruction->PrefixCount; i++)
1664 		{
1665 			switch (Instruction->Prefixes[i])
1666 			{
1667 				case PREFIX_OPERAND_SIZE:
1668 					switch (Instruction->Type)
1669 					{
1670 						case ITYPE_FSTOREENV: case ITYPE_FLOADENV: case ITYPE_FSAVE: case ITYPE_FRESTORE: continue;
1671 						default: break;
1672 					}
1673 
1674 					if (!Instruction->AnomalyOccurred)
1675 					{
1676 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: operand size prefix used with FPU/MMX/SSEx\n", VIRTUAL_ADDRESS);
1677 						goto abort;
1678 					}
1679 					X86Instruction->HasOperandSizePrefix = FALSE;
1680 					if (X86Instruction->OperandSize == 2) X86Instruction->OperandSize = 2;
1681 					break;
1682 
1683 				case PREFIX_REPNE:
1684 				case PREFIX_REP:
1685 					if (Instruction->Groups & ITYPE_FPU) { assert(Instruction->Repeat); continue; }
1686 					// The Intel manual says this results in unpredictable behavior -- it's not even
1687 					// clear which SSE prefix is used as the third opcode byte in this case
1688 					// (e.g., is it the first or last SSE prefix?)
1689 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: rep/repne used with MMX/SSEx\n", VIRTUAL_ADDRESS);
1690 					goto abort;
1691 
1692 				default:
1693 					break;
1694 			}
1695 		}
1696 	}
1697 
1698 	// Check for conflicts involving operand size
1699 	if (IS_AMD64())
1700 	{
1701 		// Check for use of rex.w=1 with an operand size prefix
1702 		if (X86Instruction->rex.w)
1703 		{
1704 			assert(X86Instruction->OperandSize == 8);
1705 			for (i = 0; i < Instruction->PrefixCount; i++)
1706 			{
1707 				if (Instruction->Prefixes[i] == PREFIX_OPERAND_SIZE)
1708 				{
1709 					X86Instruction->HasOperandSizePrefix = FALSE;
1710 					if (!Instruction->AnomalyOccurred)
1711 					{
1712 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of operand size prefix meaningless when REX.w=1\n", VIRTUAL_ADDRESS);
1713 						Instruction->AnomalyOccurred = TRUE;
1714 					}
1715 				}
1716 			}
1717 		}
1718 
1719 		// Set default operand size to 64 instead of 32 for some instructions
1720 		switch (Instruction->Type)
1721 		{
1722 			case ITYPE_PUSH: case ITYPE_POP:
1723 			case ITYPE_PUSHF: case ITYPE_POPF:
1724 			case ITYPE_ENTER: case ITYPE_LEAVE:
1725 			case ITYPE_CALL: case ITYPE_BRANCH:
1726 			case ITYPE_LOOPCC: case ITYPE_RET:
1727 				X86Instruction->HasDefault64Operand = TRUE;
1728 				break;
1729 
1730 			case ITYPE_SYSTEM:
1731 				if (Instruction->OpcodeLength != 2) break;
1732 
1733 				// lgdt/lidt/lldt/ltr
1734 				if ((Instruction->LastOpcode == 0x00 || Instruction->LastOpcode == 0x01) &&
1735 					(OpcodeExtension == 0x02 || OpcodeExtension == 0x03))
1736 				{
1737 					X86Instruction->HasDefault64Operand = TRUE;
1738 				}
1739 				break;
1740 
1741 			default:
1742 				break;
1743 		}
1744 
1745 		if (X86Instruction->HasDefault64Operand)
1746 		{
1747 			if (X86Instruction->rex.w)
1748 			{
1749 				if (!Instruction->AnomalyOccurred)
1750 				{
1751 					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of REX.w is meaningless (default operand size is 64)\n", VIRTUAL_ADDRESS);
1752 					Instruction->AnomalyOccurred = TRUE;
1753 				}
1754 				X86Instruction->rex_b &= ~8;
1755 				X86Instruction->rex.w = 0;
1756 			}
1757 
1758 			if (X86Instruction->HasOperandSizePrefix)
1759 			{
1760 				assert(X86Instruction->OperandSize == 2);
1761 				X86Instruction->HasDefault64Operand = FALSE;
1762 			}
1763 			else
1764 			{
1765 				assert(X86Instruction->OperandSize >= 4);
1766 				X86Instruction->OperandSize = 8;
1767 			}
1768 		}
1769 	}
1770 
1771 	// Make sure rep/repe/repne is set correctly based on instruction
1772 	if (Instruction->Repeat)
1773 	{
1774 		switch (Instruction->Type)
1775 		{
1776 			case ITYPE_IN:
1777 			case ITYPE_OUT:
1778 			case ITYPE_STRMOV:
1779 			case ITYPE_STRSTOR:
1780 			case ITYPE_STRLOAD:
1781 				if (X86Instruction->HasRepeatWhileNotEqualPrefix)
1782 				{
1783 					if (!Instruction->AnomalyOccurred)
1784 					{
1785 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: REPNE should only be used with cmps/scas\n", VIRTUAL_ADDRESS);
1786 						Instruction->AnomalyOccurred = TRUE;
1787 					}
1788 					// Treat it as just a "rep"
1789 					X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
1790 					X86Instruction->HasRepeatWhileEqualPrefix = TRUE;
1791 				}
1792 				break;
1793 			case ITYPE_STRCMP:
1794 				break;
1795 			default:
1796 				if (!Instruction->AnomalyOccurred)
1797 				{
1798 					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Repeat prefix used with non-string instruction\n", VIRTUAL_ADDRESS);
1799 					Instruction->AnomalyOccurred = TRUE;
1800 				}
1801 				Instruction->Repeat = FALSE;
1802 				X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
1803 				X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
1804 				break;
1805 		}
1806 	}
1807 
1808 	if (Disassemble)
1809 	{
1810 		assert(!Instruction->StringIndex);
1811 		if (X86Instruction->HasRepeatWhileEqualPrefix)
1812 		{
1813 			if (Instruction->Type == ITYPE_STRCMP) { APPENDS("repe "); }
1814 			else { APPENDS("rep "); }
1815 		}
1816 		if (X86Instruction->HasRepeatWhileNotEqualPrefix) APPENDS("repne ");
1817 		if (X86Instruction->HasLockPrefix) APPENDS("lock ");
1818 		if (X86Instruction->HasBranchTakenPrefix) APPENDS("hinttake ");
1819 		if (X86Instruction->HasBranchNotTakenPrefix) APPENDS("hintskip ");
1820 		APPENDPAD(12);
1821 		APPEND(OPCSTR, SIZE_LEFT, "%s", X86Opcode->Mnemonic);
1822 		APPENDPAD(24);
1823 	}
1824 
1825 	if (Instruction->OperandCount)
1826 	{
1827 		Instruction->Operands[0].Flags = X86Opcode->OperandFlags[0] & X86_OPFLAGS_MASK;
1828 		Instruction->Operands[1].Flags = X86Opcode->OperandFlags[1] & X86_OPFLAGS_MASK;
1829 		Instruction->Operands[2].Flags = X86Opcode->OperandFlags[2] & X86_OPFLAGS_MASK;
1830 		Address = SetOperands(Instruction, Address, Flags);
1831 		if (!Address) goto abort;
1832 		assert(!(Instruction->Operands[0].Flags & 0x7F));
1833 		assert(!(Instruction->Operands[1].Flags & 0x7F));
1834 		assert(!(Instruction->Operands[2].Flags & 0x7F));
1835 	}
1836 
1837 	Disassembler->Stage2Count++;
1838 
1839 #ifdef TEST_DISASM
1840 	//////////////////////////////////////////////////////////////////////
1841 	// Test against other disassemblers
1842 	//////////////////////////////////////////////////////////////////////
1843 
1844 	if (IS_X86_32())
1845 	{
1846 		InstructionLength = X86_GetLength(Instruction, Instruction->Address);
1847 		if (InstructionLength && Instruction->Length != InstructionLength)
1848 		{
1849 			printf("[0x%08I64X] WARNING: instruction lengths differ (%d vs %d)\n", VIRTUAL_ADDRESS, Instruction->Length, InstructionLength);
1850 			DumpInstruction(Instruction, TRUE, TRUE);
1851 			assert(0);
1852 		}
1853 	}
1854 	else if (IS_AMD64())
1855 	{
1856 		// TODO: need other amd64 (x86-64) disassembler to test against
1857 	}
1858 	else if (IS_X86_16())
1859 	{
1860 		// TODO: need other x86 16-bit disassembler to test against
1861 	}
1862 #endif
1863 
1864 	//////////////////////////////////////////////////////////////////////
1865 	// Post-operand sanity checks
1866 	//////////////////////////////////////////////////////////////////////
1867 
1868 	if (!X86Instruction->HasDstAddressing && !X86Instruction->HasSrcAddressing)
1869 	{
1870 		if (X86Instruction->HasAddressSizePrefix)
1871 		{
1872 			if (!Instruction->AnomalyOccurred)
1873 			{
1874 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: address size prefix used with no addressing\n", VIRTUAL_ADDRESS);
1875 				Instruction->AnomalyOccurred = TRUE;
1876 			}
1877 			X86Instruction->HasAddressSizePrefix = FALSE;
1878 		}
1879 
1880 		if (X86Instruction->HasSegmentOverridePrefix)
1881 		{
1882 			if (!Instruction->AnomalyOccurred)
1883 			{
1884 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: segment override used with no addressing\n", VIRTUAL_ADDRESS);
1885 				Instruction->AnomalyOccurred = TRUE;
1886 			}
1887 			X86Instruction->HasSegmentOverridePrefix = FALSE;
1888 		}
1889 	}
1890 
1891 	// Detect use of unusual segments
1892 	if (!Instruction->AnomalyOccurred && !IS_X86_16())
1893 	{
1894 		switch (X86Instruction->Segment)
1895 		{
1896 			case SEG_CS: case SEG_DS: case SEG_SS:
1897 				break;
1898 			case SEG_ES:
1899 				switch (Instruction->Type)
1900 				{
1901  					case ITYPE_IN: case ITYPE_STRMOV: case ITYPE_STRCMP: case ITYPE_STRSTOR:
1902 						break;
1903 					default:
1904 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of unexpected segment ES\n", VIRTUAL_ADDRESS);
1905 						Instruction->AnomalyOccurred = TRUE;
1906 						break;
1907 				}
1908 				break;
1909 			case SEG_FS:
1910 				if (IS_X86_32() && !(Instruction->Groups & ITYPE_EXEC)) break;
1911 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of unexpected segment FS\n", VIRTUAL_ADDRESS);
1912 				Instruction->AnomalyOccurred = TRUE;
1913 				break;
1914 			case SEG_GS:
1915 				if (IS_AMD64() && !(Instruction->Groups & ITYPE_EXEC)) break;
1916 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of unexpected segment GS\n", VIRTUAL_ADDRESS);
1917 				Instruction->AnomalyOccurred = TRUE;
1918 				break;
1919 			default:
1920 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: unexpected segment 0x%02lX\n", VIRTUAL_ADDRESS, X86Instruction->Selector);
1921 				Instruction->AnomalyOccurred = TRUE;
1922 				break;
1923 		}
1924 	}
1925 
1926 	if ((X86Opcode->OperandFlags[0] & OP_COND_EXEC) == OP_COND_EXEC)
1927 	{
1928  		assert(Instruction->Type == ITYPE_BRANCHCC || Instruction->Type == ITYPE_LOOPCC);
1929 		for (i = 0; i < Instruction->PrefixCount; i++)
1930 		{
1931 			switch (Instruction->Prefixes[i])
1932 			{
1933 				case PREFIX_BRANCH_NOT_TAKEN:
1934 					if (!Instruction->AnomalyOccurred && X86Instruction->Segment != SEG_CS)
1935 					{
1936 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Segment override used with conditional branch\n", VIRTUAL_ADDRESS);
1937 						Instruction->AnomalyOccurred = TRUE;
1938 					}
1939 					X86Instruction->HasSegmentOverridePrefix = FALSE;
1940 					X86Instruction->Segment = SEG_CS;
1941 					X86Instruction->HasBranchNotTakenPrefix = TRUE;
1942 					break;
1943 				case PREFIX_BRANCH_TAKEN:
1944 					if (!Instruction->AnomalyOccurred && X86Instruction->Segment != SEG_DS)
1945 					{
1946 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Segment override used with conditional branch\n", VIRTUAL_ADDRESS);
1947 						Instruction->AnomalyOccurred = TRUE;
1948 					}
1949 					X86Instruction->HasSegmentOverridePrefix = FALSE;
1950 					X86Instruction->Segment = SEG_CS;
1951 					X86Instruction->HasBranchTakenPrefix = TRUE;
1952 					break;
1953 			}
1954 		}
1955 	}
1956 
1957 	//
1958 	// If lock prefix is enabled, verify it is valid
1959 	//
1960 	if (X86Instruction->HasLockPrefix &&
1961 		!IsValidLockPrefix(X86Instruction, Opcode, Instruction->OpcodeLength, Group, OpcodeExtension))
1962 	{
1963 		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal use of lock prefix for instruction \"%s\"\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic);
1964 		goto abort;
1965 	}
1966 
1967 	//////////////////////////////////////////////////////////////////////
1968 	// Generate disassembly output
1969 	//////////////////////////////////////////////////////////////////////
1970 
1971 	if (Disassemble)
1972 	{
1973 		if ((Flags & DISASM_SHOWFLAGS) &&
1974 			(X86Instruction->Opcode.Preconditions || X86Instruction->Opcode.FlagsChanged || X86Instruction->Opcode.ResultsIfTrue))
1975 		{
1976 			APPENDPAD(124);
1977 			if (X86Instruction->Opcode.Preconditions)
1978 			{
1979 				Result = X86Instruction->Opcode.Preconditions;
1980 				APPENDS("COND:{ ");
1981 				if (Result & COND_L) APPENDS("L ");
1982 				if (Result & COND_NL) APPENDS("NL ");
1983 				if (Result & COND_LE) APPENDS("LE ");
1984 				if (Result & COND_NLE) APPENDS("NLE ");
1985 				if (Result & COND_G) APPENDS("G ");
1986 				if (Result & COND_NG) APPENDS("NG ");
1987 				if (Result & COND_GE) APPENDS("GE ");
1988 				if (Result & COND_NGE) APPENDS("NGE ");
1989 				if (Result & COND_A) APPENDS("A ");
1990 				if (Result & COND_NA) APPENDS("NA ");
1991 				if (Result & COND_AE) APPENDS("AE ");
1992 				if (Result & COND_NAE) APPENDS("NAE ");
1993 				if (Result & COND_B) APPENDS("B ");
1994 				if (Result & COND_NB) APPENDS("NB ");
1995 				if (Result & COND_BE) APPENDS("BE ");
1996 				if (Result & COND_NBE) APPENDS("NBE ");
1997 				if (Result & COND_E) APPENDS("E ");
1998 				if (Result & COND_NE) APPENDS("NE ");
1999 				if (Result & COND_C) APPENDS("C ");
2000 				if (Result & COND_NC) APPENDS("NC ");
2001 				if (Result & COND_Z) APPENDS("Z ");
2002 				if (Result & COND_NZ) APPENDS("NZ ");
2003 				if (Result & COND_P) APPENDS("P ");
2004 				if (Result & COND_NP) APPENDS("NP ");
2005 				if (Result & COND_PE) APPENDS("PE ");
2006 				if (Result & COND_PO) APPENDS("PO ");
2007 				if (Result & COND_O) APPENDS("O ");
2008 				if (Result & COND_NO) APPENDS("NO ");
2009 				if (Result & COND_U) APPENDS("U ");
2010 				if (Result & COND_NU) APPENDS("NU ");
2011 				if (Result & COND_S) APPENDS("S ");
2012 				if (Result & COND_NS) APPENDS("NS ");
2013 				if (Result & COND_D) APPENDS("D ");
2014 				APPENDB('}');
2015 			}
2016 
2017 			if (X86Instruction->Opcode.FlagsChanged)
2018 			{
2019 				Result = X86Instruction->Opcode.FlagsChanged;
2020 
2021 				if (Result & FLAG_SET_MASK)
2022 				{
2023 					APPENDS("SET:{ ");
2024 					if (Result & FLAG_CF_SET) APPENDS("C ");
2025 					if (Result & FLAG_DF_SET) APPENDS("D ");
2026 					if (Result & FLAG_IF_SET) APPENDS("I ");
2027 					APPENDB('}');
2028 				}
2029 
2030 				if (Result & FLAG_CLR_MASK)
2031 				{
2032 					APPENDS("CLR:{ ");
2033 					if (Result & FLAG_SF_CLR) APPENDS("S ");
2034 					if (Result & FLAG_ZF_CLR) APPENDS("Z ");
2035 					if (Result & FLAG_AF_CLR) APPENDS("A ");
2036 					if (Result & FLAG_CF_CLR) APPENDS("C ");
2037 					if (Result & FLAG_DF_CLR) APPENDS("D ");
2038 					if (Result & FLAG_IF_CLR) APPENDS("I ");
2039 					if (Result & FLAG_OF_CLR) APPENDS("O ");
2040 					if ((Result & FPU_ALL_CLR) == FPU_ALL_CLR)
2041 					{
2042 						APPENDS("FPU_ALL ");
2043 					}
2044 					else
2045 					{
2046 						if (Result & FPU_C0_CLR) APPENDS("FPU_C0 ");
2047 						if (Result & FPU_C1_CLR) APPENDS("FPU_C1 ");
2048 						if (Result & FPU_C2_CLR) APPENDS("FPU_C2 ");
2049 						if (Result & FPU_C3_CLR) APPENDS("FPU_C3 ");
2050 					}
2051 					APPENDB('}');
2052 				}
2053 
2054 				if ((Result & FLAG_MOD_MASK) == FLAG_MOD_MASK)
2055 				{
2056 					APPENDS("MOD:{ ");
2057 					if ((Result & FLAG_ALL_MOD) == FLAG_ALL_MOD)
2058 					{
2059 						APPENDS("FLAGS_ALL ");
2060 					}
2061 					else if ((Result & FLAG_COMMON_MOD) == FLAG_COMMON_MOD)
2062 					{
2063 						APPENDS("FLAGS_COMMON ");
2064 					}
2065 					else
2066 					{
2067 						if (Result & FLAG_OF_MOD) APPENDS("O ");
2068 						if (Result & FLAG_SF_MOD) APPENDS("S ");
2069 						if (Result & FLAG_ZF_MOD) APPENDS("Z ");
2070 						if (Result & FLAG_AF_MOD) APPENDS("A ");
2071 						if (Result & FLAG_PF_MOD) APPENDS("P ");
2072 						if (Result & FLAG_CF_MOD) APPENDS("C ");
2073 						if (Result & FLAG_DF_MOD) APPENDS("D ");
2074 						if (Result & FLAG_IF_MOD) APPENDS("I ");
2075 					}
2076 					if ((Result & FPU_ALL_MOD) == FPU_ALL_MOD)
2077 					{
2078 						APPENDS("FPU_ALL ");
2079 					}
2080 					else
2081 					{
2082 						if (Result & FPU_C0_MOD) APPENDS("FPU_C0 ");
2083 						if (Result & FPU_C1_MOD) APPENDS("FPU_C1 ");
2084 						if (Result & FPU_C2_MOD) APPENDS("FPU_C2 ");
2085 						if (Result & FPU_C3_MOD) APPENDS("FPU_C3 ");
2086 					}
2087 					APPENDB('}');
2088 				}
2089 
2090 				if (Result & FLAG_TOG_MASK)
2091 				{
2092 					APPENDS("TOG:{ ");
2093 					if (Result & FLAG_CF_TOG) APPENDS("C ");
2094 					APPENDB('}');
2095 				}
2096 			}
2097 		}
2098 
2099 		APPENDS("\n");
2100 	}
2101 	else
2102 	{
2103 		Instruction->String[0] = '\0';
2104 	}
2105 
2106 	if (!Instruction->Length || Instruction->Length > X86_MAX_INSTRUCTION_LEN)
2107 	{
2108 		if (!SuppressErrors) printf("[0x%08I64X] ERROR: maximum instruction length reached (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
2109 		goto abort;
2110 	}
2111 
2112 	if (!Decode)
2113 	{
2114 		Disassembler->Stage3CountNoDecode++;
2115 		return TRUE; // all work is done
2116 	}
2117 
2118 	//////////////////////////////////////////////////////////////////////
2119 	// Detect particularly interesting intructions
2120 	//////////////////////////////////////////////////////////////////////
2121 
2122 	Operand1 = &Instruction->Operands[0];
2123 	if (Instruction->Groups & ITYPE_EXEC)
2124 	{
2125 		// If it is a negative offset with a 1-byte or 2-byte offset, assume it is a loop
2126 		if (Operand1->Type == OPTYPE_OFFSET &&
2127 			Operand1->Length <= 2 && X86Instruction->Displacement < 0)
2128 		{
2129 			Instruction->CodeBranch.IsLoop = TRUE;
2130 			Instruction->CodeBranch.Operand = Operand1;
2131 		}
2132 
2133 		if (!Instruction->AnomalyOccurred &&
2134 			Operand1->TargetAddress >= (U64)Instruction->Address &&
2135 			Operand1->TargetAddress < (U64)Instruction->Address + Instruction->Length)
2136 		{
2137 			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: branch into the middle of an instruction\n", VIRTUAL_ADDRESS);
2138 			Instruction->AnomalyOccurred = TRUE;
2139 		}
2140 
2141 		switch (Instruction->Type)
2142 		{
2143 			case ITYPE_BRANCH:
2144 				Operand1->Flags |= OP_ADDRESS;
2145 				assert(Instruction->OperandCount == 1);
2146 				if (!(Operand1->Flags & (OP_GLOBAL|OP_FAR)))
2147 				{
2148 					assert(!X86Instruction->HasSelector);
2149 					X86Instruction->Segment = SEG_CS;
2150 				}
2151 
2152 				if (Operand1->TargetAddress)
2153 				{
2154 					assert(!Instruction->CodeBranch.AddressOffset);
2155 					Instruction->CodeBranch.Count = 1;
2156 					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
2157 					Instruction->CodeBranch.Operand = Operand1;
2158 				}
2159 				// If there is both a base and index register, the Result will probably be too wrong
2160 				// to even guess
2161 				else if (X86Instruction->HasFullDisplacement &&
2162 					 ((X86Instruction->HasBaseRegister && !X86Instruction->HasIndexRegister) ||
2163 					 (!X86Instruction->HasBaseRegister && X86Instruction->HasIndexRegister)))
2164 				{
2165 					assert(Operand1->Length <= 0xFF);
2166 					if (!X86Instruction->Scale)
2167 					{
2168 						if (Operand1->Length) X86Instruction->Scale = (U8)Operand1->Length;
2169 						else X86Instruction->Scale = X86Instruction->OperandSize;
2170 					}
2171 					assert(Operand1->Length <= 0xFF);
2172 					tmpScale = MAX(X86Instruction->Scale, Operand1->Length);
2173 
2174 					assert(tmpScale <= 16);
2175 					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
2176 					for (i = 0; i < MAX_CODE_REFERENCE_COUNT; i++) Instruction->CodeBranch.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
2177 					Instruction->CodeBranch.Count = i;
2178 					Instruction->CodeBranch.IsIndirect = TRUE;
2179 					Instruction->CodeBranch.Operand = Operand1;
2180 				}
2181 				break;
2182 
2183 			case ITYPE_CALL:
2184 				Instruction->Groups |= ITYPE_STACK;
2185 				Instruction->CodeBranch.IsCall = TRUE;
2186 				Operand1->Flags |= OP_ADDRESS;
2187 				assert(Instruction->OperandCount == 1);
2188 				if (!(Operand1->Flags & (OP_GLOBAL|OP_FAR)))
2189 				{
2190 					assert(!X86Instruction->HasSelector);
2191 					X86Instruction->Segment = SEG_CS;
2192 				}
2193 
2194 				if (Operand1->TargetAddress)
2195 				{
2196 					assert(!Instruction->CodeBranch.AddressOffset);
2197 					Instruction->CodeBranch.Count = 1;
2198 					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
2199 					Instruction->CodeBranch.Operand = Operand1;
2200 				}
2201 				// If there is both a base and index register, the Result will probably be too wrong
2202 				// to even guess
2203 				else if (X86Instruction->HasFullDisplacement &&
2204 					((X86Instruction->HasBaseRegister && !X86Instruction->HasIndexRegister) ||
2205 					 (!X86Instruction->HasBaseRegister && X86Instruction->HasIndexRegister)))
2206 				{
2207 					//DISASM_OUTPUT(("[0x%08I64X] Scale %d, displacement 0x%08I64x\n", VIRTUAL_ADDRESS, X86Instruction->Scale, X86Instruction->Displacement));
2208 					if (!X86Instruction->Scale)
2209 					{
2210 						assert(Operand1->Length <= 0xFF);
2211 						if (Operand1->Length) X86Instruction->Scale = (U8)Operand1->Length;
2212 						else X86Instruction->Scale = X86Instruction->OperandSize;
2213 					}
2214 					tmpScale = MAX(X86Instruction->Scale, Operand1->Length);
2215 
2216 					assert(tmpScale <= 16);
2217 					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
2218 					assert(X86Instruction->Scale > 1);
2219 					for (i = 0; i < MAX_CODE_REFERENCE_COUNT; i++) Instruction->CodeBranch.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
2220 					Instruction->CodeBranch.Count = i;
2221 					Instruction->CodeBranch.IsIndirect = TRUE;
2222 					Instruction->CodeBranch.Operand = Operand1;
2223 				}
2224 				break;
2225 
2226 			case ITYPE_BRANCHCC:
2227 				assert(Instruction->OperandCount == 1);
2228 				assert(Operand1->Flags & OP_ADDRESS);
2229 				assert(Operand1->Type == OPTYPE_OFFSET);
2230 				if (!(Operand1->Flags & (OP_GLOBAL|OP_FAR)))
2231 				{
2232 					assert(!X86Instruction->HasSelector);
2233 					X86Instruction->Segment = SEG_CS;
2234 				}
2235 
2236 				if (Operand1->TargetAddress)
2237 				{
2238 					assert(!Instruction->CodeBranch.AddressOffset);
2239 					Instruction->CodeBranch.Count = 2;
2240 					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
2241 					Instruction->CodeBranch.Addresses[1] = (U64)Instruction->Address + Instruction->Length;
2242 					Instruction->CodeBranch.Operand = Operand1;
2243 				}
2244 				break;
2245 
2246 			case ITYPE_LOOPCC:
2247 				Instruction->CodeBranch.IsLoop = TRUE;
2248 				assert(Instruction->OperandCount == 1);
2249 				assert(Operand1->Flags & OP_ADDRESS);
2250 				assert(Operand1->Type == OPTYPE_OFFSET);
2251 				assert(!(Operand1->Flags & (OP_GLOBAL|OP_FAR)));
2252 				if (Operand1->TargetAddress)
2253 				{
2254 					assert(!Instruction->CodeBranch.AddressOffset);
2255 					Instruction->CodeBranch.Count = 2;
2256 					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
2257 					Instruction->CodeBranch.Addresses[1] = (U64)Instruction->Address + Instruction->Length;
2258 					Instruction->CodeBranch.Operand = Operand1;
2259 				}
2260 				break;
2261 
2262 			case ITYPE_RET:
2263 				Instruction->Groups |= ITYPE_STACK;
2264 				break;
2265 
2266 			default:
2267 				break; // do nothing
2268 		}
2269 	}
2270 	else // possible data instruction
2271 	{
2272 		for (i = 0, Operand = Instruction->Operands; i < Instruction->OperandCount; i++, Operand++)
2273 		{
2274 			if (Operand->TargetAddress)
2275 			{
2276 				if (Operand->Flags & OP_DST)
2277 				{
2278 					assert(!Instruction->DataDst.Count);
2279 					Instruction->DataDst.Count = 1;
2280 					Instruction->DataDst.Addresses[0] = Operand->TargetAddress;
2281 					Instruction->DataDst.DataSize = Operand->Length;
2282 					Instruction->DataDst.Operand = Operand;
2283 					DISASM_OUTPUT(("[0x%08I64X] Write of size %d to 0x%04I64X\n", VIRTUAL_ADDRESS, Operand->Length, Operand->TargetAddress));
2284 				}
2285 				if (Operand->Flags & OP_SRC)
2286 				{
2287 					assert(!Instruction->DataSrc.Count);
2288 					Instruction->DataSrc.Count = 1;
2289 					Instruction->DataSrc.Addresses[0] = Operand->TargetAddress;
2290 					Instruction->DataSrc.DataSize = Operand->Length;
2291 					Instruction->DataSrc.Operand = Operand;
2292 					DISASM_OUTPUT(("[0x%08I64X] Read of size %d to 0x%04I64X\n", VIRTUAL_ADDRESS, Operand->Length, Operand->TargetAddress));
2293 				}
2294 			}
2295 
2296 			// If there is both a base and index register, the Result will probably be too wrong
2297 			// to even guess
2298 			else if (Operand->Flags & OP_GLOBAL &&
2299 				((X86Instruction->HasBaseRegister && !X86Instruction->HasIndexRegister) ||
2300 				 (!X86Instruction->HasBaseRegister && X86Instruction->HasIndexRegister)))
2301 			{
2302 				DISASM_OUTPUT(("[0x%08I64X] Data reference (scale %d, size %d, displacement 0x%08I64x)\n", VIRTUAL_ADDRESS, X86Instruction->Scale, Operand->Length, X86Instruction->Displacement));
2303 				if (!X86Instruction->Scale)
2304 				{
2305 					assert(Operand->Length <= 0xFF);
2306 					if (Operand->Length) X86Instruction->Scale = (U8)Operand->Length;
2307 					else X86Instruction->Scale = X86Instruction->OperandSize;
2308 				}
2309 				tmpScale = MAX(X86Instruction->Scale, Operand->Length);
2310 
2311 				assert(X86Instruction->HasFullDisplacement);
2312 				if (Operand->Flags & OP_DST)
2313 				{
2314 					assert(!Instruction->DataDst.Count);
2315 					assert(tmpScale <= 16);
2316 					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
2317 					for (i = 0; i < MAX_DATA_REFERENCE_COUNT; i++) Instruction->DataDst.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
2318 					Instruction->DataDst.Count = i;
2319 					Instruction->DataDst.DataSize = Operand->Length;
2320 					Instruction->DataDst.Operand = Operand;
2321 				}
2322 				if (Operand->Flags & OP_SRC)
2323 				{
2324 					assert(!Instruction->DataSrc.Count);
2325 					assert(tmpScale <= 16);
2326 					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
2327 					for (i = 0; i < MAX_DATA_REFERENCE_COUNT; i++) Instruction->DataSrc.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
2328 					Instruction->DataSrc.Count = i;
2329 					Instruction->DataSrc.DataSize = Operand->Length;
2330 					Instruction->DataSrc.Operand = Operand;
2331 				}
2332 			}
2333 		}
2334 	}
2335 
2336 	if (Instruction->Groups & ITYPE_STACK)
2337 	{
2338 		switch (Instruction->Type)
2339 		{
2340 			case ITYPE_PUSH:
2341 				assert(Instruction->OperandCount == 1 && Operand1->Length);
2342 				Instruction->StackChange = -Operand1->Length;
2343 				SANITY_CHECK_ADDRESS_SIZE();
2344 				break;
2345 
2346 			case ITYPE_POP:
2347 				assert(Instruction->OperandCount == 1 && Operand1->Length);
2348 				Instruction->StackChange = Operand1->Length;
2349 				SANITY_CHECK_ADDRESS_SIZE();
2350 				break;
2351 
2352 			case ITYPE_PUSHA:
2353 				Instruction->StackChange = -(X86Instruction->OperandSize * 8); // xAX, xCX, xDX, xBX, xBP, xSP, xSI, xDI
2354 				SANITY_CHECK_ADDRESS_SIZE();
2355 				break;
2356 
2357 			case ITYPE_POPA:
2358 				Instruction->StackChange = X86Instruction->OperandSize * 8; // xDI, xSI, xSP, xBP, xBX, xDX, xCX, xAX
2359 				SANITY_CHECK_ADDRESS_SIZE();
2360 				break;
2361 
2362 			case ITYPE_PUSHF:
2363 				Instruction->StackChange = -Operand1->Length;
2364 				Instruction->NeedsEmulation = TRUE;
2365 				SANITY_CHECK_ADDRESS_SIZE();
2366 				break;
2367 
2368 			case ITYPE_POPF:
2369 				Instruction->StackChange = Operand1->Length;
2370 				Instruction->NeedsEmulation = TRUE;
2371 				SANITY_CHECK_ADDRESS_SIZE();
2372 				break;
2373 
2374 			case ITYPE_ENTER:
2375 				if (!Instruction->AnomalyOccurred)
2376 				{
2377 					if (Instruction->Operands[1].Value_U64 & 3)
2378 					{
2379 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: ENTER has invalid operand 2\n", VIRTUAL_ADDRESS);
2380 						Instruction->AnomalyOccurred = TRUE;
2381 					}
2382 					if (Instruction->Operands[2].Value_U64 & ~0x1F)
2383 					{
2384 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: ENTER has invalid operand 3\n", VIRTUAL_ADDRESS);
2385 						Instruction->AnomalyOccurred = TRUE;
2386 					}
2387 				}
2388 				SANITY_CHECK_ADDRESS_SIZE();
2389 				Instruction->Operands[2].Value_U64 &= 0x1F;
2390 
2391 				// frame pointer + stack space
2392 				i = Operand1->Length + (U32)Instruction->Operands[1].Value_U64;
2393 				Instruction->StackChange = -((LONG)i);
2394 				i = (U32)Instruction->Operands[2].Value_U64 * Operand1->Length;
2395 				Instruction->StackChange -= i;
2396 				break;
2397 
2398 			case ITYPE_LEAVE:
2399 				// This will do "mov esp, ebp; pop ebp" so the StackChange size is dynamic
2400 				SANITY_CHECK_ADDRESS_SIZE();
2401 				break;
2402 
2403 			case ITYPE_CALL:
2404 				Instruction->StackChange = -X86Instruction->OperandSize;
2405 				SANITY_CHECK_ADDRESS_SIZE();
2406 				break;
2407 
2408 			case ITYPE_RET:
2409 				Instruction->StackChange = X86Instruction->OperandSize;
2410 
2411 				switch (Opcode)
2412 				{
2413 					case 0xC3: // ret with no args
2414 						break;
2415 
2416 					case 0xC2: // ret with 1 arg
2417 						if (!Instruction->AnomalyOccurred && (Operand1->Value_U64 & 3))
2418 						{
2419 							if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: ret has invalid operand 1\n", VIRTUAL_ADDRESS);
2420 							Instruction->AnomalyOccurred = TRUE;
2421 						}
2422 						Instruction->StackChange += (LONG)Operand1->Value_U64;
2423 						break;
2424 
2425 					case 0xCB: // far ret with no args
2426 						Instruction->StackChange *= 2; // account for segment
2427 						Instruction->StackChange += (LONG)Operand1->Value_U64;
2428 						break;
2429 
2430 					case 0xCA: // far ret with 1 arg
2431 						if (!Instruction->AnomalyOccurred && (Operand1->Value_U64 & 3))
2432 						{
2433 							if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: retf has invalid operand 1\n", VIRTUAL_ADDRESS);
2434 							Instruction->AnomalyOccurred = TRUE;
2435 						}
2436 						Instruction->StackChange *= 2; // account for segment
2437 						Instruction->StackChange += (LONG)Operand1->Value_U64;
2438 						break;
2439 				}
2440 				SANITY_CHECK_ADDRESS_SIZE();
2441 				break;
2442 
2443 			case ITYPE_ADD:
2444 			case ITYPE_XCHGADD:
2445 				if (Instruction->Operands[1].Value_S64) Instruction->StackChange = (LONG)(Instruction->Operands[1].Value_S64);
2446 				break;
2447 			case ITYPE_SUB:
2448 				if (Instruction->Operands[1].Value_S64) Instruction->StackChange = (LONG)(-Instruction->Operands[1].Value_S64);
2449 				break;
2450 			case ITYPE_MOV:
2451 			case ITYPE_AND:
2452 				break;
2453 
2454 			default:
2455 				if (!Instruction->AnomalyOccurred)
2456 				{
2457 					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Instruction \"%s\" is modifying the stack\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic);
2458 					Instruction->AnomalyOccurred = TRUE;
2459 				}
2460 				break;
2461 		}
2462 
2463 		if (!Instruction->AnomalyOccurred &&
2464 			((X86Instruction->OperandSize != 2 && (Instruction->StackChange & 3)) || (Instruction->StackChange & 1)))
2465 		{
2466 			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: \"%s\" has invalid stack change 0x%02lX\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Instruction->StackChange);
2467 			Instruction->AnomalyOccurred = TRUE;
2468 		}
2469 	}
2470 
2471 	if (Instruction->Groups & ITYPE_TRAPS)
2472 	{
2473 		switch (Instruction->Type)
2474 		{
2475 			case ITYPE_TRAP:
2476 			case ITYPE_TRAPCC:
2477 			case ITYPE_TRAPRET:
2478 			case ITYPE_BOUNDS:
2479 			case ITYPE_DEBUG:
2480 			case ITYPE_TRACE:
2481 			case ITYPE_INVALID:
2482 			case ITYPE_OFLOW:
2483 				Instruction->NeedsEmulation = TRUE;
2484 				break;
2485 			default:
2486 				assert(0);
2487 				break;
2488 		}
2489 	}
2490 
2491 	if (Instruction->Groups & ITYPE_SYSTEM)
2492 	{
2493 		switch (Instruction->Type)
2494 		{
2495 			case ITYPE_CPUID:
2496 			case ITYPE_SYSCALL:
2497 			case ITYPE_SYSCALLRET:
2498 				// This doesn't require privileges
2499 				break;
2500 
2501 			case ITYPE_HALT:
2502 			case ITYPE_IN:
2503 			case ITYPE_OUT:
2504 			default:
2505 				Instruction->NeedsEmulation = TRUE;
2506 				break;
2507 		}
2508 	}
2509 
2510 	Disassembler->Stage3CountWithDecode++;
2511 	return TRUE;
2512 
2513 abort:
2514 	if (!SuppressErrors)
2515 	{
2516 #ifdef TEST_DISASM
2517 		printf("Dump of 0x%04I64X:\n", VIRTUAL_ADDRESS);
2518 		__try { DumpAsBytes(stdout, Instruction->Address, (ULONG_PTR)VIRTUAL_ADDRESS, 16, TRUE); }
2519 		__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {}
2520 #endif
2521 		fflush(stdout);
2522 	}
2523 	return FALSE;
2524 }
2525 
2526 // Address = address to first byte after the opcode (e.g., first byte of ModR/M byte or
2527 // immediate value
2528 //
2529 // Returns the address immediately following the operand (e.g., the next operand or the
2530 // start of the next instruction
SetOperands(INSTRUCTION * Instruction,U8 * Address,U32 Flags)2531 INTERNAL U8 *SetOperands(INSTRUCTION *Instruction, U8 *Address, U32 Flags)
2532 {
2533 	INSTRUCTION_OPERAND *Operand;
2534 	U32 Index, OperandIndex;
2535 	S64 Displacement = 0;
2536 	U8 Register;
2537 	U32 OperandFlags, OperandType, AddressMode, Segment;
2538 	U8 Opcode;
2539 	MODRM modrm;
2540 	REX rex;
2541 	REX_MODRM rex_modrm;
2542 	X86_OPCODE *X86Opcode;
2543 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
2544 	BOOL Decode = Flags & DISASM_DECODE;
2545 	BOOL Disassemble = Flags & DISASM_DISASSEMBLE;
2546 	BOOL SuppressErrors = Flags & DISASM_SUPPRESSERRORS;
2547 
2548 	Opcode = Instruction->LastOpcode;
2549 	X86Opcode = &X86Instruction->Opcode;
2550 
2551 	// Setup Mod R/M byte
2552 	if (X86Instruction->HasModRM)
2553 	{
2554 		SET_MODRM(X86Instruction->modrm, X86Instruction->modrm_b);
2555 		modrm = X86Instruction->modrm;
2556 		rex = X86Instruction->rex;
2557 		SET_REX_MODRM(X86Instruction->rex_modrm, rex, modrm);
2558 		rex_modrm = X86Instruction->rex_modrm;
2559 		//DISASM_OUTPUT(("[0x%08I64X] ModRM = 0x%02X (mod=%d, reg=%d, rm=%d)\n", VIRTUAL_ADDRESS, X86Instruction->modrm_b, modrm.mod, rex_modrm.reg, rex_modrm.rm));
2560 		INSTR_INC(1); // increment Instruction->Length and address
2561 	}
2562 	else
2563 	{
2564 		// initialize them to 0
2565 		modrm = X86Instruction->modrm;
2566 		rex = X86Instruction->rex;
2567 		rex_modrm = X86Instruction->rex_modrm;
2568 	}
2569 
2570 	for (OperandIndex = 0; OperandIndex < Instruction->OperandCount; OperandIndex++)
2571 	{
2572 		Operand = &Instruction->Operands[OperandIndex];
2573 		assert(!(Operand->Flags & 0x7F));
2574 
2575 		OperandFlags = X86Opcode->OperandFlags[OperandIndex] & X86_OPFLAGS_MASK;
2576 		OperandType = X86Opcode->OperandFlags[OperandIndex] & X86_OPTYPE_MASK;
2577 		AddressMode = X86Opcode->OperandFlags[OperandIndex] & X86_AMODE_MASK;
2578 		if (Decode && OperandIndex != 0) APPENDS(", ");
2579 
2580 		switch (OperandType)
2581 		{
2582 			////////////////////////////////////////////////////////////
2583 			// Special operand types with no associated addressing mode
2584 			////////////////////////////////////////////////////////////
2585 
2586 			case OPTYPE_0:
2587 				if (!Decode) continue;
2588 				Operand->Value_U64 = 0;
2589 				Operand->Type = OPTYPE_IMM;
2590 				//DISASM_OUTPUT(("[SetOperand] const 0\n"));
2591 				if (Disassemble)
2592 				{
2593 					APPENDS("<0>");
2594 					X86_WRITE_OPFLAGS();
2595 				}
2596 				continue;
2597 			case OPTYPE_1:
2598 				if (!Decode) continue;
2599 				Operand->Value_U64 = 1;
2600 				Operand->Type = OPTYPE_IMM;
2601 				//DISASM_OUTPUT(("[SetOperand] const 1\n"));
2602 				if (Disassemble)
2603 				{
2604 					APPENDS("<1>");
2605 					X86_WRITE_OPFLAGS();
2606 				}
2607 				continue;
2608 			case OPTYPE_FF:
2609 				if (!Decode) continue;
2610 				Operand->Value_U64 = 0xFF;
2611 				Operand->Type = OPTYPE_IMM;
2612 				//DISASM_OUTPUT(("[SetOperand] const 0xff\n"));
2613 				if (Disassemble)
2614 				{
2615 					APPENDS("<0xFF>");
2616 					X86_WRITE_OPFLAGS();
2617 				}
2618 				continue;
2619 
2620 			case OPTYPE_TSC:
2621 				if (!Decode) continue;
2622 				Operand->Length = 8;
2623 				Operand->Type = OPTYPE_SPECIAL;
2624 				//DISASM_OUTPUT(("[SetOperand] TSC\n"));
2625 				if (Disassemble)
2626 				{
2627 					APPENDS("<TSC_MSR>");
2628 					X86_WRITE_OPFLAGS();
2629 				}
2630 				continue;
2631 
2632 			case OPTYPE_CS_MSR:
2633 				if (!Decode) continue;
2634 				Operand->Length = 8;
2635 				Operand->Type = OPTYPE_SPECIAL;
2636 				//DISASM_OUTPUT(("[SetOperand] CS MSR\n"));
2637 				if (Disassemble)
2638 				{
2639 					APPENDS("<CS_MSR>");
2640 					X86_WRITE_OPFLAGS();
2641 				}
2642 				continue;
2643 			case OPTYPE_EIP_MSR:
2644 				if (!Decode) continue;
2645 				Operand->Length = 8;
2646 				Operand->Type = OPTYPE_SPECIAL;
2647 				//DISASM_OUTPUT(("[SetOperand] EIP MSR\n"));
2648 				if (Disassemble)
2649 				{
2650 					APPENDS("<EIP_MSR>");
2651 					X86_WRITE_OPFLAGS();
2652 				}
2653 				continue;
2654 			case OPTYPE_ESP_MSR:
2655 				if (!Decode) continue;
2656 				Operand->Length = 8;
2657 				Operand->Type = OPTYPE_SPECIAL;
2658 				//DISASM_OUTPUT(("[SetOperand] ESP MSR\n"));
2659 				if (Disassemble)
2660 				{
2661 					APPENDS("<ESP_MSR>");
2662 					X86_WRITE_OPFLAGS();
2663 				}
2664 				continue;
2665 			case OPTYPE_KERNELBASE_MSR:
2666 				if (!Decode) continue;
2667 				Operand->Length = 8;
2668 				Operand->Type = OPTYPE_SPECIAL;
2669 				//DISASM_OUTPUT(("[SetOperand] KernelBase MSR\n"));
2670 				if (Disassemble)
2671 				{
2672 					APPENDS("<KRNLBASE_MSR>");
2673 					X86_WRITE_OPFLAGS();
2674 				}
2675 				continue;
2676 
2677 			case OPTYPE_STAR_MSR:
2678 				if (!Decode) continue;
2679 				Operand->Length = 8;
2680 				Operand->Type = OPTYPE_SPECIAL;
2681 				//DISASM_OUTPUT(("[SetOperand] KernelBase MSR\n"));
2682 				if (Disassemble)
2683 				{
2684 					APPENDS("<STAR_MSR>");
2685 					X86_WRITE_OPFLAGS();
2686 				}
2687 				continue;
2688 			case OPTYPE_CSTAR_MSR:
2689 				assert(!IS_AMD64());
2690 				if (!Decode) continue;
2691 				Operand->Length = 8;
2692 				Operand->Type = OPTYPE_SPECIAL;
2693 				//DISASM_OUTPUT(("[SetOperand] CSTAR MSR\n"));
2694 				if (Disassemble)
2695 				{
2696 					APPENDS("<CSTAR_MSR>");
2697 					X86_WRITE_OPFLAGS();
2698 				}
2699 				continue;
2700 			case OPTYPE_LSTAR_MSR:
2701 				assert(IS_AMD64());
2702 				if (!Decode) continue;
2703 				Operand->Length = 8;
2704 				Operand->Type = OPTYPE_SPECIAL;
2705 				//DISASM_OUTPUT(("[SetOperand] LSTAR MSR\n"));
2706 				if (Disassemble)
2707 				{
2708 					APPENDS("<LSTAR_MSR>");
2709 					X86_WRITE_OPFLAGS();
2710 				}
2711 				continue;
2712 			case OPTYPE_FMASK_MSR:
2713 				if (!Decode) continue;
2714 				Operand->Length = 8;
2715 				Operand->Type = OPTYPE_SPECIAL;
2716 				//DISASM_OUTPUT(("[SetOperand] FMASK MSR\n"));
2717 				if (Disassemble)
2718 				{
2719 					APPENDS("<FMASK_MSR>");
2720 					X86_WRITE_OPFLAGS();
2721 				}
2722 				continue;
2723 
2724 			case OP_REG:
2725 				if (!Decode) continue;
2726 				// The reg field is included in the opcode
2727 				Operand->Length = X86Instruction->OperandSize;
2728 				Register = X86_GET_REG64(Opcode);
2729 				switch (X86Instruction->OperandSize)
2730 				{
2731 					case 8:
2732 						Operand->Register = AMD64_64BIT_OFFSET + Register;
2733 						break;
2734 					case 4:
2735 						Operand->Register = X86_32BIT_OFFSET + Register;
2736 						CHECK_AMD64_REG();
2737 						break;
2738 					case 2:
2739 						Operand->Register = X86_16BIT_OFFSET + Register;
2740 						CHECK_AMD64_REG();
2741 						break;
2742 					case 1:
2743 						Operand->Register = X86_8BIT_OFFSET + Register;
2744 						if (X86Instruction->rex_b) CHECK_AMD64_REG();
2745 						break;
2746 					default:
2747 						assert(0);
2748 						return NULL;
2749 				}
2750 				X86_SET_REG(Register);
2751 
2752 				//DISASM_OUTPUT(("[SetOperand] OP_REG %s\n", X86_Registers[Operand->Register]));
2753 				if (Disassemble)
2754 				{
2755 					APPENDB('<'); APPENDS(X86_Registers[Operand->Register]); APPENDB('>');
2756 					X86_WRITE_OPFLAGS();
2757 				}
2758 				continue;
2759 
2760 			case OPTYPE_REG8:
2761 				if (!Decode) continue;
2762 				// The reg field is included in the opcode
2763 				Operand->Length = 1;
2764 				Register = X86_GET_REG64(Opcode);
2765 				Operand->Register = X86_8BIT_OFFSET + Register;
2766 				CHECK_AMD64_REG();
2767 				X86_SET_REG(Register);
2768 
2769 				//DISASM_OUTPUT(("[SetOperand] OP_REG %s\n", X86_Registers[Operand->Register]));
2770 				if (Disassemble)
2771 				{
2772 					APPENDB('<'); APPENDS(X86_Registers[Operand->Register]); APPENDB('>');
2773 					X86_WRITE_OPFLAGS();
2774 				}
2775 				continue;
2776 
2777 			case OPTYPE_REG_AL:
2778 				if (!Decode) continue;
2779 				Operand->Length = 1;
2780 				Operand->Register = X86_REG_AL;
2781 				X86_SET_REG(0);
2782 				//DISASM_OUTPUT(("[SetOperand] reg AL\n"));
2783 				if (Disassemble)
2784 				{
2785 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2786 					X86_WRITE_OPFLAGS();
2787 				}
2788 				continue;
2789 			case OPTYPE_REG_CL:
2790 				if (!Decode) continue;
2791 				Operand->Length = 1;
2792 				Operand->Register = X86_REG_CL;
2793 				X86_SET_REG(0);
2794 				//DISASM_OUTPUT(("[SetOperand] reg CL\n"));
2795 				if (Disassemble)
2796 				{
2797 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2798 					X86_WRITE_OPFLAGS();
2799 				}
2800 				continue;
2801 			case OPTYPE_REG_AH:
2802 				if (!Decode) continue;
2803 				Operand->Length = 1;
2804 				Operand->Register = X86_REG_AH;
2805 				X86_SET_REG(0);
2806 				//DISASM_OUTPUT(("[SetOperand] reg AH\n"));
2807 				if (Disassemble)
2808 				{
2809 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2810 					X86_WRITE_OPFLAGS();
2811 				}
2812 				continue;
2813 			case OPTYPE_REG_AX:
2814 				if (!Decode) continue;
2815 				Operand->Length = 2;
2816 				Operand->Register = X86_REG_AX;
2817 				X86_SET_REG(0);
2818 				//DISASM_OUTPUT(("[SetOperand] reg AX\n"));
2819 				if (Disassemble)
2820 				{
2821 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2822 					X86_WRITE_OPFLAGS();
2823 				}
2824 				continue;
2825 			case OPTYPE_REG_DX:
2826 				if (!Decode) continue;
2827 				Operand->Length = 2;
2828 				Operand->Register = X86_REG_DX;
2829 				X86_SET_REG(0);
2830 				//DISASM_OUTPUT(("[SetOperand] reg DX\n"));
2831 				if (Disassemble)
2832 				{
2833 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2834 					X86_WRITE_OPFLAGS();
2835 				}
2836 				continue;
2837 			case OPTYPE_REG_ECX:
2838 				if (!Decode) continue;
2839 				Operand->Length = 4;
2840 				Operand->Register = X86_REG_ECX;
2841 				X86_SET_REG(0);
2842 				//DISASM_OUTPUT(("[SetOperand] reg ECX\n"));
2843 				if (Disassemble)
2844 				{
2845 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2846 					X86_WRITE_OPFLAGS();
2847 				}
2848 				continue;
2849 
2850 			case OPTYPE_REG_xBP:
2851 				if (!Decode) continue;
2852 				Operand->Length = X86Instruction->OperandSize;
2853 				switch (X86Instruction->OperandSize)
2854 				{
2855 					case 8: Operand->Register = AMD64_REG_RBP; break;
2856 					case 4: Operand->Register = X86_REG_EBP; break;
2857 					case 2: Operand->Register = X86_REG_BP; break;
2858 					default: assert(0); return NULL;
2859 				}
2860 				X86_SET_REG(0);
2861 				//DISASM_OUTPUT(("[SetOperand] xAX_BIG (size = %d)\n", Operand->Length));
2862 				if (Disassemble)
2863 				{
2864 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2865 					X86_WRITE_OPFLAGS();
2866 				}
2867 				continue;
2868 
2869 			case OPTYPE_REG_xAX_BIG:
2870 				if (!Decode) continue;
2871 				Operand->Length = X86Instruction->OperandSize;
2872 				switch (X86Instruction->OperandSize)
2873 				{
2874 					case 8: Operand->Register = AMD64_REG_RAX; break;
2875 					case 4: Operand->Register = X86_REG_EAX; break;
2876 					case 2: Operand->Register = X86_REG_AX; break;
2877 					default: assert(0); return NULL;
2878 				}
2879 				X86_SET_REG(0);
2880 				//DISASM_OUTPUT(("[SetOperand] xAX_BIG (size = %d)\n", Operand->Length));
2881 				if (Disassemble)
2882 				{
2883 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2884 					X86_WRITE_OPFLAGS();
2885 				}
2886 				continue;
2887 			case OPTYPE_REG_xAX_SMALL:
2888 				if (!Decode) continue;
2889 				Operand->Length = X86Instruction->OperandSize >> 1;
2890 				switch (X86Instruction->OperandSize)
2891 				{
2892 					case 8: Operand->Register = X86_REG_EAX; break;
2893 					case 4: Operand->Register = X86_REG_AX; break;
2894 					case 2: Operand->Register = X86_REG_AL; break;
2895 					default: assert(0); return NULL;
2896 				}
2897 				X86_SET_REG(0);
2898 				//DISASM_OUTPUT(("[SetOperand] xAX_SMALL (size = %d)\n", Operand->Length));
2899 				if (Disassemble)
2900 				{
2901 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2902 					X86_WRITE_OPFLAGS();
2903 				}
2904 				continue;
2905 
2906 			case OPTYPE_xCX_HI_xBX_LO:
2907 				if (!Decode) continue;
2908 				Operand->Length = X86Instruction->OperandSize << 1;
2909 				if (Disassemble)
2910 				{
2911 					switch (X86Instruction->OperandSize)
2912 					{
2913 						case 8: APPENDS("<RCX:RBX>"); break;
2914 						case 4: APPENDS("<ECX:EBX>"); break;
2915 						case 2: APPENDS("<CX:BX>"); break;
2916 						default: assert(0); return NULL;
2917 					}
2918 					X86_WRITE_OPFLAGS();
2919 				}
2920 				//DISASM_OUTPUT(("[SetOperand] xCX_BIG:xBX_BIG (size = %d)\n", Operand->Length));
2921 				continue;
2922 			case OPTYPE_xDX_HI_xAX_LO:
2923 				if (!Decode) continue;
2924 				Operand->Length = X86Instruction->OperandSize << 1;
2925 				if (Disassemble)
2926 				{
2927 					switch (X86Instruction->OperandSize)
2928 					{
2929 						case 8: APPENDS("<RDX:RAX>"); break;
2930 						case 4: APPENDS("<EDX:EAX>"); break;
2931 						case 2: APPENDS("<DX:AX>"); break;
2932 						default: assert(0); return NULL;
2933 					}
2934 					X86_WRITE_OPFLAGS();
2935 				}
2936 				//DISASM_OUTPUT(("[SetOperand] xDX_BIG:xAX_BIG (size = %d)\n", Operand->Length));
2937 				continue;
2938 
2939 			case OPTYPE_EDX_HI_EAX_LO:
2940 				if (!Decode) continue;
2941 				Operand->Length = 8;
2942 				//DISASM_OUTPUT(("[SetOperand] EDX:EAX\n"));
2943 				if (Disassemble)
2944 				{
2945 					APPENDS("<EDX:EAX>");
2946 					X86_WRITE_OPFLAGS();
2947 				}
2948 				continue;
2949 
2950 			case OPTYPE_EDX_ECX_EBX_EAX:
2951 				Operand->Length = 32;
2952 				//DISASM_OUTPUT(("[SetOperand] EDX:ECX:EBX:EAX\n"));
2953 				if (Disassemble)
2954 				{
2955 					APPENDS("<EDX:ECX:EBX:EAX>");
2956 					X86_WRITE_OPFLAGS();
2957 				}
2958 				continue;
2959 
2960 			case OPTYPE_FLAGS:
2961 				if (!Decode) continue;
2962 				Operand->Length = 2;
2963 				Operand->Flags |= OP_REG;
2964 				Operand->Register = X86_REG_FLAGS;
2965 				//DISASM_OUTPUT(("[SetOperand] reg FLAGS\n"));
2966 				if (Disassemble)
2967 				{
2968 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2969 					X86_WRITE_OPFLAGS();
2970 				}
2971 				continue;
2972 
2973 			case OPTYPE_xFLAGS:
2974 				if (!Decode) continue;
2975 				Operand->Length = X86Instruction->OperandSize;
2976 				Operand->Flags |= OP_REG;
2977 				switch (X86Instruction->OperandSize)
2978 				{
2979 					case 8: Operand->Register = AMD64_REG_RFLAGS; break;
2980 					case 4: Operand->Register = X86_REG_EFLAGS; break;
2981 					case 2: Operand->Register = X86_REG_FLAGS; break;
2982 					default: assert(0); return NULL;
2983 				}
2984 				//DISASM_OUTPUT(("[SetOperand] reg xFLAGS (size = %d)\n", Operand->Length));
2985 				if (Disassemble)
2986 				{
2987 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
2988 					X86_WRITE_OPFLAGS();
2989 				}
2990 				continue;
2991 
2992 			case OPTYPE_CS:
2993 				if (!Decode) continue;
2994 				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
2995 				else Operand->Length = X86Instruction->OperandSize;
2996 				Operand->Register = X86_SEG_CS;
2997 				Operand->Flags |= OP_REG;
2998 				//DISASM_OUTPUT(("[SetOperand] seg CS\n"));
2999 				if (Disassemble)
3000 				{
3001 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3002 					X86_WRITE_OPFLAGS();
3003 				}
3004 				continue;
3005 			case OPTYPE_DS:
3006 				if (!Decode) continue;
3007 				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
3008 				else Operand->Length = X86Instruction->OperandSize;
3009 				Operand->Register = X86_SEG_DS;
3010 				Operand->Flags |= OP_REG;
3011 				//DISASM_OUTPUT(("[SetOperand] seg DS\n"));
3012 				if (Disassemble)
3013 				{
3014 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3015 					X86_WRITE_OPFLAGS();
3016 				}
3017 				continue;
3018 			case OPTYPE_ES:
3019 				if (!Decode) continue;
3020 				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
3021 				else Operand->Length = X86Instruction->OperandSize;
3022 				Operand->Register = X86_SEG_ES;
3023 				Operand->Flags |= OP_REG;
3024 				//DISASM_OUTPUT(("[SetOperand] seg ES\n"));
3025 				if (Disassemble)
3026 				{
3027 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3028 					X86_WRITE_OPFLAGS();
3029 				}
3030 				continue;
3031 			case OPTYPE_FS:
3032 				if (!Decode) continue;
3033 				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
3034 				else Operand->Length = X86Instruction->OperandSize;
3035 				Operand->Register = X86_SEG_FS;
3036 				Operand->Flags |= OP_REG;
3037 				//DISASM_OUTPUT(("[SetOperand] seg FS\n"));
3038 				if (Disassemble)
3039 				{
3040 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3041 					X86_WRITE_OPFLAGS();
3042 				}
3043 				continue;
3044 			case OPTYPE_GS:
3045 				if (!Decode) continue;
3046 				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
3047 				else Operand->Length = X86Instruction->OperandSize;
3048 				Operand->Register = X86_SEG_GS;
3049 				Operand->Flags |= OP_REG;
3050 				//DISASM_OUTPUT(("[SetOperand] seg GS\n"));
3051 				if (Disassemble)
3052 				{
3053 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3054 					X86_WRITE_OPFLAGS();
3055 				}
3056 				continue;
3057 			case OPTYPE_SS:
3058 				if (!Decode) continue;
3059 				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
3060 				else Operand->Length = X86Instruction->OperandSize;
3061 				Operand->Register = X86_SEG_SS;
3062 				Operand->Flags |= OP_REG;
3063 				//DISASM_OUTPUT(("[SetOperand] seg SS\n"));
3064 				if (Disassemble)
3065 				{
3066 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3067 					X86_WRITE_OPFLAGS();
3068 				}
3069 				continue;
3070 
3071 			case OPTYPE_CR0:
3072 				if (!Decode) continue;
3073 				Operand->Length = X86Instruction->OperandSize;
3074 				Operand->Register = X86_REG_CR0;
3075 				Operand->Flags |= OP_REG;
3076 				//DISASM_OUTPUT(("[SetOperand] reg CR0\n"));
3077 				if (Disassemble)
3078 				{
3079 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3080 					X86_WRITE_OPFLAGS();
3081 				}
3082 				continue;
3083 
3084 			case OPTYPE_STx:
3085 				if (!Decode) continue;
3086 				Operand->Length = 10;
3087 				Operand->Type = OPTYPE_FLOAT;
3088 				Operand->Flags |= OP_REG;
3089 				Register = X86_GET_REG(X86Instruction->modrm_b);
3090 				Operand->Register = X86_FPU_OFFSET + Register;
3091 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_STx: reg st(%d)\n", Register));
3092 				if (Disassemble)
3093 				{
3094 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3095 					X86_WRITE_OPFLAGS();
3096 				}
3097 				continue;
3098 
3099 			case OPTYPE_ST0:
3100 				if (!Decode) continue;
3101 				Operand->Length = 10;
3102 				Operand->Type = OPTYPE_FLOAT;
3103 				Operand->Flags |= OP_REG;
3104 				Operand->Register = X86_REG_ST0;
3105 				if (Disassemble)
3106 				{
3107 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3108 					X86_WRITE_OPFLAGS();
3109 				}
3110 				continue;
3111 
3112 			case OPTYPE_ST1:
3113 				if (!Decode) continue;
3114 				Operand->Length = 10;
3115 				Operand->Type = OPTYPE_FLOAT;
3116 				Operand->Flags |= OP_REG;
3117 				Operand->Register = X86_REG_ST1;
3118 				if (Disassemble)
3119 				{
3120 					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
3121 					X86_WRITE_OPFLAGS();
3122 				}
3123 				continue;
3124 
3125 			case OPTYPE_FPU_STATUS:
3126 				if (!Decode) continue;
3127 				Operand->Length = 2;
3128 				if (Disassemble)
3129 				{
3130 					APPENDS("<FPUSTAT>");
3131 					X86_WRITE_OPFLAGS();
3132 				}
3133 				continue;
3134 
3135 			case OPTYPE_FPU_CONTROL:
3136 				if (!Decode) continue;
3137 				Operand->Length = 2;
3138 				if (Disassemble)
3139 				{
3140 					APPENDS("<FPUCTRL>");
3141 					X86_WRITE_OPFLAGS();
3142 				}
3143 				continue;
3144 
3145 			case OPTYPE_FPU_TAG:
3146 				if (!Decode) continue;
3147 				Operand->Length = 2;
3148 				if (Disassemble)
3149 				{
3150 					APPENDS("<FPUTAG>");
3151 					X86_WRITE_OPFLAGS();
3152 				}
3153 				continue;
3154 
3155 			case OPTYPE_FLDZ:
3156 				if (!Decode) continue;
3157 				Operand->Type = OPTYPE_FLOAT;
3158 				Operand->Length = 10;
3159 				if (Disassemble)
3160 				{
3161 					APPENDS("<0.0>");
3162 					X86_WRITE_OPFLAGS();
3163 				}
3164 				continue;
3165 			case OPTYPE_FLD1:
3166 				if (!Decode) continue;
3167 				Operand->Type = OPTYPE_FLOAT;
3168 				Operand->Length = 10;
3169 				if (Disassemble)
3170 				{
3171 					APPENDS("<1.0>");
3172 					X86_WRITE_OPFLAGS();
3173 				}
3174 				continue;
3175 			case OPTYPE_FLDPI:
3176 				if (!Decode) continue;
3177 				Operand->Type = OPTYPE_FLOAT;
3178 				Operand->Length = 10;
3179 				if (Disassemble)
3180 				{
3181 					APPENDS("<pi>");
3182 					X86_WRITE_OPFLAGS();
3183 				}
3184 				continue;
3185 			case OPTYPE_FLDL2T:
3186 				if (!Decode) continue;
3187 				Operand->Type = OPTYPE_FLOAT;
3188 				Operand->Length = 10;
3189 				if (Disassemble)
3190 				{
3191 					APPENDS("<log_2 10>");
3192 					X86_WRITE_OPFLAGS();
3193 				}
3194 				continue;
3195 			case OPTYPE_FLDL2E:
3196 				if (!Decode) continue;
3197 				Operand->Type = OPTYPE_FLOAT;
3198 				Operand->Length = 10;
3199 				if (Disassemble)
3200 				{
3201 					APPENDS("<log_2 e>");
3202 					X86_WRITE_OPFLAGS();
3203 				}
3204 				continue;
3205 			case OPTYPE_FLDLG2:
3206 				if (!Decode) continue;
3207 				Operand->Type = OPTYPE_FLOAT;
3208 				Operand->Length = 10;
3209 				if (Disassemble)
3210 				{
3211 					APPENDS("<log_10 2>");
3212 					X86_WRITE_OPFLAGS();
3213 				}
3214 				continue;
3215 			case OPTYPE_FLDLN2:
3216 				if (!Decode) continue;
3217 				Operand->Type = OPTYPE_FLOAT;
3218 				Operand->Length = 10;
3219 				if (Disassemble)
3220 				{
3221 					APPENDS("<ln 2>");
3222 					X86_WRITE_OPFLAGS();
3223 				}
3224 				continue;
3225 
3226 			////////////////////////////////////////////////////////////
3227 			// Fixed sizes regardless of operand size
3228 			////////////////////////////////////////////////////////////
3229 
3230 			case OPTYPE_b: // byte regardless of operand size
3231 				Operand->Length = 1;
3232 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_b (size 1, signed %d)\n", ((OperandFlags & OP_SIGNED) != 0)));
3233 				break;
3234 
3235 			case OPTYPE_w: // word regardless of operand size
3236 				Operand->Length = 2;
3237 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_w (size 2)\n"));
3238 				break;
3239 
3240 			case OPTYPE_d: // dword regardless of operand size
3241 				Operand->Length = 4;
3242 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_d (size 4)\n"));
3243 				break;
3244 
3245 			case OPTYPE_q: // qword regardless of operand size
3246 				Operand->Length = 8;
3247 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_q (size 8)\n"));
3248 				break;
3249 
3250 			case OPTYPE_o: // oword regardless of operand size
3251 				Operand->Length = 16;
3252 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_o (size 16)\n"));
3253 				break;
3254 
3255 			case OPTYPE_dt: // 6-byte or 10-byte pseudo descriptor (sgdt, lgdt, sidt, lidt)
3256 				if (IS_AMD64()) Operand->Length = 10;
3257 				else Operand->Length = 6;
3258 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_dt (%d bytes)\n", Operand->Length));
3259 				break;
3260 
3261 			case OPTYPE_cpu:
3262 				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Undocumented loadall instruction?\n", VIRTUAL_ADDRESS);
3263 				Instruction->AnomalyOccurred = TRUE;
3264 				Operand->Length = 204;
3265 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_cpu (size 204)\n"));
3266 				break;
3267 
3268 			////////////////////////////////////////////////////////////
3269 			// Sizes depending on the operand size
3270 			////////////////////////////////////////////////////////////
3271 
3272 			case OPTYPE_z: // word if operand size is 16 bits and dword otherwise
3273 				switch (X86Instruction->OperandSize)
3274 				{
3275 					case 8: case 4: Operand->Length = 4; break;
3276 					case 2: Operand->Length = 2; break;
3277 					default: assert(0); return NULL;
3278 				}
3279 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_z (length %d)\n", Operand->Length));
3280 				break;
3281 
3282 			case OPTYPE_v: // word, dword, or qword
3283 				Operand->Length = X86Instruction->OperandSize;
3284 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_v (size %d, signed = %d)\n", Operand->Length, ((OperandFlags & OP_SIGNED) != 0)));
3285 				break;
3286 
3287 			case OPTYPE_a: // two word or dword operands in memory (used only by bound)
3288 				assert(Instruction->OpcodeBytes[0] == X86_BOUND);
3289 				switch (X86Instruction->OperandSize)
3290 				{
3291 					case 8: case 4: Operand->Length = 8; break;
3292 					case 2: Operand->Length = 4; break;
3293 					default: assert(0); return NULL;
3294 				}
3295 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_a (size %d)\n", Operand->Length));
3296 				break;
3297 
3298 			case OPTYPE_p: // 32-bit or 48-bit pointer depending on operand size
3299 				if (!Instruction->AnomalyOccurred && X86Instruction->HasSegmentOverridePrefix)
3300 				{
3301 					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Segment override used when segment is explicit\n", VIRTUAL_ADDRESS);
3302 					Instruction->AnomalyOccurred = TRUE;
3303 				}
3304 				switch (X86Instruction->OperandSize)
3305 				{
3306 					case 8: case 4: Operand->Length = 6; break;
3307 					case 2: Operand->Length = 4; break;
3308 					default: assert(0); return NULL;
3309 				}
3310 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_p (length %d)\n", Operand->Length));
3311 				break;
3312 
3313 			case OPTYPE_dq: // dword or qword
3314 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_dq (size 4 or 8)\n"));
3315 				switch (X86Instruction->OperandSize)
3316 				{
3317 					case 8: Operand->Length = 8; break;
3318 					case 4: case 2: Operand->Length = 4; break;
3319 					default: assert(0); return NULL;
3320 				}
3321 				break;
3322 
3323 			case OPTYPE_mw: // a word if the destination operand is memory
3324 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_mw (size 0)\n"));
3325 				assert(X86Instruction->HasModRM);
3326 				if (modrm.mod == 3) Operand->Length = X86Instruction->OperandSize; // using register
3327 				else Operand->Length = 2; // using memory
3328 				break;
3329 
3330 			case OPTYPE_lea:
3331 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_lea (size 0)\n"));
3332 				assert(OperandIndex == 1);
3333 				Operand->Length = Instruction->Operands[0].Length;
3334 				break;
3335 
3336 			////////////////////////////////////////////////////////////
3337 			// FPU types
3338 			////////////////////////////////////////////////////////////
3339 
3340 			case OPTYPE_ps: // packed single real
3341 				Operand->Length = 4;
3342 				Operand->Type = OPTYPE_FLOAT;
3343 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_ps (packed single real)\n"));
3344 				break;
3345 			case OPTYPE_pd: // packed double real
3346 				Operand->Length = 8;
3347 				Operand->Type = OPTYPE_FLOAT;
3348 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_pd (packed double real)\n"));
3349 				break;
3350 			case OPTYPE_pb: // packed BCD
3351 				Operand->Length = 10;
3352 				Operand->Type = OPTYPE_BCD;
3353 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_pb (packed BCD)\n"));
3354 				break;
3355 			case OPTYPE_ss: // scalar single real
3356 				Operand->Length = 4;
3357 				Operand->Type = OPTYPE_FLOAT;
3358 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_ss (single real)\n"));
3359 				break;
3360 			case OPTYPE_sd: // scalar double real
3361 				Operand->Length = 8;
3362 				Operand->Type = OPTYPE_FLOAT;
3363 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_sd (double real)\n"));
3364 				break;
3365 			case OPTYPE_se: // extended real
3366 				Operand->Length = 10;
3367 				Operand->Type = OPTYPE_FLOAT;
3368 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_se (extended real)\n"));
3369 				break;
3370 
3371 			case OPTYPE_fev: // FPU environment (28 bytes in 32-bit modes, 14 bytes in 16-bit real mode)
3372 				switch (X86Instruction->OperandSize)
3373 				{
3374 					case 8: case 4: Operand->Length = 28; break;
3375 					case 2: Operand->Length = 14; break;
3376 					default: assert(0); return NULL;
3377 				}
3378 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_fev (FPU environment, length %d)\n", Operand->Length));
3379 				break;
3380 
3381 			case OPTYPE_fst1: // FPU state (108 bytes in 32-bit modes, 94 bytes in 16-bit real mode)
3382 				switch (X86Instruction->OperandSize)
3383 				{
3384 					case 8: case 4: Operand->Length = 108; break;
3385 					case 2: Operand->Length = 94; break;
3386 					default: assert(0); return NULL;
3387 				}
3388 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_fst1 (FPU state, length %d)\n", Operand->Length));
3389 				break;
3390 
3391 			case OPTYPE_fst2: // 512 bytes for FPU state (FPU + MMX + XXM + MXCSR)
3392 				Operand->Length = 512;
3393 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_fst2 (FPU + MMX + XXM + MXCSR state, length 512)\n"));
3394 				break;
3395 
3396 			case OPTYPE_sso:
3397 				if (modrm.mod == 3) // from register
3398 				{
3399 					Operand->Length = 16;
3400 				}
3401 				else // from memory
3402 				{
3403 					Operand->Length = 4;
3404 					Operand->Type = OPTYPE_FLOAT;
3405 				}
3406 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_sso (single real or oword)\n"));
3407 				break;
3408 
3409 			case OPTYPE_sdo:
3410 				if (modrm.mod == 3) // from register
3411 				{
3412 					Operand->Length = 16;
3413 				}
3414 				else // from memory
3415 				{
3416 					Operand->Length = 8;
3417 					Operand->Type = OPTYPE_FLOAT;
3418 				}
3419 				//DISASM_OUTPUT(("[SetOperand] OPTYPE_sso (double real or oword)\n"));
3420 				break;
3421 
3422 			default:
3423 				assert(0);
3424 				return NULL;
3425 		}
3426 
3427 		switch (AddressMode)
3428 		{
3429 			////////////////////////////////////////////////////////////
3430 			// Special types
3431 			////////////////////////////////////////////////////////////
3432 
3433 			case AMODE_xlat: // DS:[EBX+AL]
3434 				if (!Decode) continue;
3435 				assert(Operand->Length == 1);
3436 				Operand->Flags |= OP_ADDRESS | OP_REG;
3437 				Operand->Type = OPTYPE_STRING;
3438 
3439 				switch (X86Instruction->AddressSize)
3440 				{
3441 					case 8: Operand->Register = AMD64_REG_RBX; break;
3442 					case 4: Operand->Register = X86_REG_EBX; break;
3443 					case 2: Operand->Register = X86_REG_BX; break;
3444 					default: assert(0); return NULL;
3445 				}
3446 				X86_SET_ADDR();
3447 				X86Instruction->Scale = 1;
3448 				X86Instruction->BaseRegister = Operand->Register;
3449 				X86Instruction->HasBaseRegister = TRUE;
3450 				X86Instruction->IndexRegister = X86_REG_AL;
3451 				X86Instruction->HasIndexRegister = TRUE;
3452 
3453 				//DISASM_OUTPUT(("[SetOperand] AMODE_xlat (DS:[EBX+AL])\n"));
3454 				if (Disassemble)
3455 				{
3456 					APPEND(OPCSTR, SIZE_LEFT, "%s:[%s]",
3457 						Segments[X86Instruction->Segment], X86_Registers[Operand->Register]);
3458 					X86_WRITE_OPFLAGS();
3459 				}
3460 				continue;
3461 
3462 			////////////////////////////////////////////////////////////
3463 			// Without mod R/M byte
3464 			////////////////////////////////////////////////////////////
3465 
3466 			case AMODE_I: // immediate value
3467 				if (Decode)
3468 				{
3469 					Operand->Type = OPTYPE_IMM;
3470 					switch (Operand->Length)
3471 					{
3472 						case 8:
3473 							if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S64 *)Address);
3474 							else Operand->Value_U64 = (U64)*((U64 *)Address);
3475 							break;
3476 						case 4:
3477 							if (!(OperandFlags & OP_SIGNED) && OperandIndex == 1 &&
3478 								(Instruction->Operands[0].Flags & (OP_REG|OP_ADDRESS)) &&
3479 								Instruction->Operands[0].Length == 8)
3480 							{
3481 								// For some opcodes the second operand is a sign-extended imm32 value
3482 								assert(X86Instruction->OperandSize == 8);
3483 								switch (Instruction->Type)
3484 								{
3485 									case ITYPE_AND:
3486 									case ITYPE_ADD:
3487 									case ITYPE_XCHGADD:
3488 									case ITYPE_CMP:
3489 									case ITYPE_MOV:
3490 									case ITYPE_SUB:
3491 									case ITYPE_TEST:
3492 									case ITYPE_OR:
3493 									case ITYPE_XOR:
3494 										assert(OperandIndex == 1);
3495 										Operand->Value_S64 = (S64)*((S32 *)Address);
3496 										break;
3497 									default:
3498 										assert(0);
3499 										if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S32 *)Address);
3500 										else Operand->Value_U64 = (U64)*((U32 *)Address);
3501 										break;
3502 								}
3503 							}
3504 							else
3505 							{
3506 								if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S32 *)Address);
3507 								else Operand->Value_U64 = (U64)*((U32 *)Address);
3508 							}
3509 							break;
3510 						case 2:
3511 							if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S16 *)Address);
3512 							else Operand->Value_U64 = (U64)*((U16 *)Address);
3513 							break;
3514 						case 1:
3515 							if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S8 *)Address);
3516 							else Operand->Value_U64 = (U64)*((U8 *)Address);
3517 							break;
3518 						default:
3519 							assert(0);
3520 							return NULL;
3521 					}
3522 				}
3523 				INSTR_INC(Operand->Length); // increment Instruction->Length and address
3524 				assert(X86Instruction->OperandSize >= Operand->Length);
3525 				if (Instruction->Type == ITYPE_PUSH) Operand->Length = X86Instruction->OperandSize;
3526 
3527 				//DISASM_OUTPUT(("[SetOperand] AMODE_I (immediate data)\n"));
3528 				if (Disassemble)
3529 				{
3530 					X86_WRITE_IMMEDIATE();
3531 					X86_WRITE_OPFLAGS();
3532 				}
3533 				continue;
3534 
3535 			case AMODE_J: // IP-relative jump offset
3536 				SANITY_CHECK_ADDRESS_SIZE();
3537 				if (Decode)
3538 				{
3539 					Operand->Flags |= OP_IPREL | OP_SIGNED | OP_REG | OP_ADDRESS;
3540 					Operand->Type = OPTYPE_OFFSET;
3541 					switch (X86Instruction->OperandSize)
3542 					{
3543 						case 8: Operand->Register = AMD64_REG_RIP; break;
3544 						case 4: Operand->Register = X86_REG_EIP; break;
3545 						case 2: Operand->Register = X86_REG_IP; break;
3546 						default: assert(0); return NULL;
3547 					}
3548 					switch (Operand->Length)
3549 					{
3550 						case 8: X86Instruction->Displacement = *((S64 *)Address); break;
3551 						case 4: X86Instruction->Displacement = (S64)*((S32 *)Address); break;
3552 						case 2: X86Instruction->Displacement = (S64)*((S16 *)Address); break;
3553 						case 1: X86Instruction->Displacement = (S64)*((S8 *)Address); break;
3554 						default: assert(0); return NULL;
3555 					}
3556 
3557 					Operand->Value_S64 = X86Instruction->Displacement;
3558 					X86Instruction->Relative = TRUE;
3559 
3560 					if ((Operand->Flags & OP_COND) && !X86Instruction->Displacement)
3561 					{
3562 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Both conditions of branch go to same address\n", VIRTUAL_ADDRESS);
3563 						Instruction->AnomalyOccurred = TRUE;
3564 					}
3565 				}
3566 
3567 				INSTR_INC(Operand->Length); // increment Instruction->Length and address
3568 				if (!Decode) continue;
3569 
3570 				assert((Operand->Flags & OP_EXEC) && (Instruction->Groups & ITYPE_EXEC));
3571 				Operand->TargetAddress = ApplyDisplacement((U64)Address, Instruction);
3572 				X86Instruction->Relative = TRUE;
3573 				X86_SET_ADDR();
3574 				SANITY_CHECK_SEGMENT_OVERRIDE();
3575 				X86Instruction->HasSegmentOverridePrefix = FALSE;
3576 				X86Instruction->Segment = SEG_CS;
3577 				X86Instruction->BaseRegister = Operand->Register;
3578 				X86Instruction->HasBaseRegister = TRUE;
3579 				assert(Instruction->OperandCount == 1);
3580 				//DISASM_OUTPUT(("[SetOperand] AMODE_J (branch with relative offset)\n"));
3581 				if (Disassemble)
3582 				{
3583 					X86_WRITE_IP_OFFSET(Operand);
3584 					X86_WRITE_OPFLAGS();
3585 				}
3586 				continue;
3587 
3588 			case AMODE_O: // word/dword offset
3589 				Operand->Type = OPTYPE_OFFSET;
3590 				Operand->Flags |= OP_ADDRESS;
3591 				SANITY_CHECK_OPERAND_SIZE();
3592 				switch (X86Instruction->AddressSize)
3593 				{
3594 					case 8:
3595 						if (Operand->Flags & OP_SIGNED) X86Instruction->Displacement = *((S64 *)Address);
3596 						else X86Instruction->Displacement = (S64)*((U64 *)Address);
3597 						break;
3598 					case 4:
3599 						if (Operand->Flags & OP_SIGNED) X86Instruction->Displacement = (S64)*((S32 *)Address);
3600 						else X86Instruction->Displacement = (S64)*((U32 *)Address);
3601 						break;
3602 					case 2:
3603 						if (Operand->Flags & OP_SIGNED) X86Instruction->Displacement = (S64)*((S16 *)Address);
3604 						else X86Instruction->Displacement = (S64)*((U16 *)Address);
3605 						break;
3606 					default:
3607 						assert(0);
3608 						return FALSE;
3609 				}
3610 
3611 				INSTR_INC(X86Instruction->AddressSize); // increment Instruction->Length and address
3612 				if (!Decode) continue;
3613 
3614 				X86Instruction->HasFullDisplacement = TRUE;
3615 				X86_SET_ADDR();
3616 				X86_SET_TARGET();
3617 				assert(X86Instruction->Segment == SEG_DS || X86Instruction->HasSegmentOverridePrefix);
3618 				//DISASM_OUTPUT(("[SetOperand] AMODE_O (offset)\n"));
3619 				if (Disassemble)
3620 				{
3621 					X86_WRITE_OFFSET(Operand);
3622 					X86_WRITE_OPFLAGS();
3623 				}
3624 				continue;
3625 
3626 			case AMODE_A: // absolute address
3627 				Operand->Flags |= OP_ADDRESS | OP_FAR;
3628 				SANITY_CHECK_ADDRESS_SIZE();
3629 				SANITY_CHECK_SEGMENT_OVERRIDE();
3630 				X86Instruction->HasSelector = TRUE;
3631 				X86Instruction->HasSegmentOverridePrefix = FALSE;
3632 				switch (Operand->Length)
3633 				{
3634 					case 6:
3635 						X86Instruction->Segment = *((U16 *)Address); INSTR_INC(2);
3636 						X86Instruction->Displacement = (S64)*((S32 *)Address); INSTR_INC(4);
3637 						break;
3638 					case 4:
3639 						X86Instruction->Segment = *((U16 *)Address); INSTR_INC(2);
3640 						X86Instruction->Displacement = (S64)*((S16 *)Address); INSTR_INC(2);
3641 						break;
3642 					default:
3643 						assert(0);
3644 						return FALSE;
3645 				}
3646 				if (!Decode) continue;
3647 				X86Instruction->HasFullDisplacement = TRUE;
3648 				X86_SET_ADDR();
3649 				X86_SET_TARGET();
3650 				//DISASM_OUTPUT(("[SetOperand] AMODE_A (absolute address)\n"));
3651 				if (Disassemble)
3652 				{
3653 					X86_WRITE_OFFSET(Operand);
3654 					X86_WRITE_OPFLAGS();
3655 				}
3656 				continue;
3657 
3658 			case AMODE_X: // DS:[ESI]
3659 				if (!Decode) continue;
3660 				Operand->Flags |= OP_ADDRESS | OP_REG;
3661 				Operand->Type = OPTYPE_STRING;
3662 				switch (X86Instruction->AddressSize)
3663 				{
3664 					case 8: Operand->Register = AMD64_REG_RSI; break;
3665 					case 4: Operand->Register = X86_REG_ESI; break;
3666 					case 2: Operand->Register = X86_REG_SI; break;
3667 					default: assert(0); return NULL;
3668 				}
3669 
3670 				X86Instruction->BaseRegister = Operand->Register;
3671 				X86Instruction->HasBaseRegister = TRUE;
3672 				X86_SET_ADDR();
3673 				if (!X86Instruction->HasSegmentOverridePrefix) X86Instruction->Segment = SEG_DS;
3674 
3675 				//DISASM_OUTPUT(("[SetOperand] AMODE_X (addressing via DS:[ESI])\n"));
3676 				if (Disassemble)
3677 				{
3678 					APPEND(OPCSTR, SIZE_LEFT, "%s:[%s]",
3679 						Segments[X86Instruction->Segment], X86_Registers[Operand->Register]);
3680 					X86_WRITE_OPFLAGS();
3681 				}
3682 				continue;
3683 
3684 			case AMODE_Y: // ES:[EDI]
3685 				if (!Decode) continue;
3686 				Operand->Flags |= OP_ADDRESS | OP_REG;
3687 				Operand->Type = OPTYPE_STRING;
3688 				switch (X86Instruction->AddressSize)
3689 				{
3690 					case 8: Operand->Register = AMD64_REG_RDI; break;
3691 					case 4: Operand->Register = X86_REG_EDI; break;
3692 					case 2: Operand->Register = X86_REG_DI; break;
3693 					default: assert(0); return NULL;
3694 				}
3695 
3696 				X86Instruction->BaseRegister = Operand->Register;
3697 				X86Instruction->HasBaseRegister = TRUE;
3698 				X86_SET_ADDR();
3699 				if (X86Instruction->HasSegmentOverridePrefix)
3700 				{
3701 					if (!Instruction->AnomalyOccurred)
3702 					{
3703 						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: segment override used with AMODE_Y\n", VIRTUAL_ADDRESS);
3704 						Instruction->AnomalyOccurred = TRUE;
3705 					}
3706 					Segment = X86Instruction->DstSegment = SEG_ES;
3707 					X86Instruction->HasDstSegment = TRUE;
3708 				}
3709 				else
3710 				{
3711 					Segment = X86Instruction->Segment = SEG_ES;
3712 				}
3713 
3714 				//DISASM_OUTPUT(("[SetOperand] AMODE_Y (addressing via ES:[EDI])\n"));
3715 				if (Disassemble)
3716 				{
3717 					APPEND(OPCSTR, SIZE_LEFT, "%s:[%s]",
3718 						Segments[Segment], X86_Registers[Operand->Register]);
3719 					X86_WRITE_OPFLAGS();
3720 				}
3721 				continue;
3722 
3723 			////////////////////////////////////////////////////////////
3724 			// Mod R/M byte with only registers
3725 			// Handle that case here since it is straightforward
3726 			////////////////////////////////////////////////////////////
3727 
3728 			case AMODE_PR: // modrm.rm = mmx register and modrm.mod = 11
3729 				assert(X86Instruction->HasModRM);
3730 				if (modrm.mod != 3)
3731 				{
3732 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod != 3 for AMODE_PR (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
3733 					goto abort;
3734 				}
3735 				else if (rex_modrm.rm > 7)
3736 				{
3737 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: invalid mmx register %d for AMODE_PR (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.rm, X86Instruction->Opcode.Mnemonic);
3738 					goto abort;
3739 				}
3740 				else if (X86Instruction->OperandSize == 2)
3741 				{
3742 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_PR illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
3743 					goto abort;
3744 				}
3745 				if (!Decode) continue;
3746 
3747 				Operand->Flags |= OP_REG;
3748 				Operand->Register = X86_MMX_OFFSET + rex_modrm.rm;
3749 				X86_SET_REG(0);
3750 
3751 				if (Disassemble)
3752 				{
3753 					assert(X86_Registers[Operand->Register]);
3754 					APPENDS(X86_Registers[Operand->Register]);
3755 					X86_WRITE_OPFLAGS();
3756 				}
3757 				//DISASM_OUTPUT(("[SetOperand] AMODE_PR (MMX register)\n"));
3758 				continue;
3759 
3760 			case AMODE_VR: // modrm.rm = xmm register and modrm.mod = 11
3761 				assert(X86Instruction->HasModRM);
3762 				if (modrm.mod != 3)
3763 				{
3764 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod != 3 for AMODE_VR (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
3765 					goto abort;
3766 				}
3767 				else if (X86Instruction->OperandSize == 2)
3768 				{
3769 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_VR illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
3770 					goto abort;
3771 				}
3772 				if (!Decode) continue;
3773 
3774 				Operand->Flags |= OP_REG;
3775 				Operand->Register = X86_XMM_OFFSET + rex_modrm.rm;
3776 				X86_SET_REG(0);
3777 
3778 				if (Disassemble)
3779 				{
3780 					APPENDS(X86_Registers[Operand->Register]);
3781 					X86_WRITE_OPFLAGS();
3782 				}
3783 				//DISASM_OUTPUT(("[SetOperand] AMODE_VR (XMM register)\n"));
3784 				continue;
3785 
3786 			case AMODE_P: // modrm.reg = mmx register
3787 				assert(X86Instruction->HasModRM);
3788 				if (rex_modrm.reg > 7)
3789 				{
3790 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: invalid mmx register %d for AMODE_P (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.reg, X86Instruction->Opcode.Mnemonic);
3791 					goto abort;
3792 				}
3793 				else if (X86Instruction->OperandSize == 2)
3794 				{
3795 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_P illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
3796 					goto abort;
3797 				}
3798 				if (!Decode) continue;
3799 
3800 				Operand->Flags |= OP_REG;
3801 				Operand->Register = X86_MMX_OFFSET + rex_modrm.reg;
3802 				X86_SET_REG(0);
3803 
3804 				if (Disassemble)
3805 				{
3806 					APPENDS(X86_Registers[Operand->Register]);
3807 					X86_WRITE_OPFLAGS();
3808 				}
3809 				//DISASM_OUTPUT(("[SetOperand] AMODE_P (MMX register)\n"));
3810 				continue;
3811 
3812 			case AMODE_V: // modrm.reg = xmm register
3813 				assert(X86Instruction->HasModRM);
3814 				if (X86Instruction->OperandSize == 2)
3815 				{
3816 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_P illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
3817 					goto abort;
3818 				}
3819 				if (!Decode) continue;
3820 
3821 				Operand->Flags |= OP_REG;
3822 				Operand->Register = X86_XMM_OFFSET + rex_modrm.reg; break;
3823 				X86_SET_REG(0);
3824 
3825 				if (Disassemble)
3826 				{
3827 					APPENDS(X86_Registers[Operand->Register]);
3828 					X86_WRITE_OPFLAGS();
3829 				}
3830 				//DISASM_OUTPUT(("[SetOperand] AMODE_V (XMM register)\n"));
3831 				continue;
3832 
3833 			case AMODE_R: // modrm.rm is general register and modrm.mod = 11
3834 				assert(X86Instruction->HasModRM);
3835 				if (modrm.mod != 3)
3836 				{
3837 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod != 3 for AMODE_R (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
3838 					goto abort;
3839 				}
3840 				if (!Decode) continue;
3841 				Operand->Flags |= OP_REG;
3842 				switch (Operand->Length)
3843 				{
3844 					case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.rm; break;
3845 					case 4: Operand->Register = X86_32BIT_OFFSET, rex_modrm.rm; CHECK_AMD64_REG(); break;
3846 					case 2: Operand->Register = X86_16BIT_OFFSET, rex_modrm.rm; CHECK_AMD64_REG(); break;
3847 					case 1: Operand->Register = X86_8BIT_OFFSET, rex_modrm.rm; if (X86Instruction->rex_b) CHECK_AMD64_REG(); break;
3848 					default: assert(0); return NULL;
3849 				}
3850 				X86_SET_REG(rex_modrm.rm);
3851 				if (Disassemble)
3852 				{
3853 					APPENDS(X86_Registers[Operand->Register]);
3854 					X86_WRITE_OPFLAGS();
3855 				}
3856 				//DISASM_OUTPUT(("[SetOperand] AMODE_R (general register)\n"));
3857 				continue;
3858 
3859 			case AMODE_G: // modrm.reg = general register
3860 				assert(X86Instruction->HasModRM);
3861 				if (!Decode) continue;
3862 				Operand->Flags |= OP_REG;
3863 				switch (Operand->Length)
3864 				{
3865 					case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.reg; break;
3866 					case 4: Operand->Register = X86_32BIT_OFFSET + rex_modrm.reg; CHECK_AMD64_REG(); break;
3867 					case 2: Operand->Register = X86_16BIT_OFFSET + rex_modrm.reg; CHECK_AMD64_REG(); break;
3868 					case 1: Operand->Register = X86_8BIT_OFFSET + rex_modrm.reg; if (X86Instruction->rex_b) CHECK_AMD64_REG(); break;
3869 					default: assert(0); return NULL;
3870 				}
3871 				X86_SET_REG(rex_modrm.reg);
3872 				if (Disassemble)
3873 				{
3874 					APPENDS(X86_Registers[Operand->Register]);
3875 					X86_WRITE_OPFLAGS();
3876 				}
3877 				//DISASM_OUTPUT(("[SetOperand] AMODE_G (general register)\n"));
3878 				continue;
3879 
3880 			case AMODE_S: // modrm.reg = segment register
3881 				assert(X86Instruction->HasModRM);
3882 				if (!Decode) continue;
3883 				Operand->Flags |= OP_REG;
3884 				switch (X86Instruction->OperandSize)
3885 				{
3886 					case 8:
3887 					case 4:
3888 					case 2:
3889 						if (rex_modrm.reg <= 5) Operand->Register = X86_SEGMENT_OFFSET + rex_modrm.reg;
3890 						break;
3891 					default:
3892 						assert(0);
3893 						return NULL;
3894 				}
3895 
3896 				X86_SET_REG(0);
3897 				if (Disassemble)
3898 				{
3899 					if (rex_modrm.reg > 5) APPEND(OPCSTR, SIZE_LEFT, "seg_%02X", rex_modrm.reg);
3900 					else APPENDS(X86_Registers[Operand->Register]);
3901 					X86_WRITE_OPFLAGS();
3902 				}
3903 				//DISASM_OUTPUT(("[SetOperand] AMODE_S (segment register)\n"));
3904 				continue;
3905 
3906 			case AMODE_T: // modrm.reg = test register
3907 				assert(X86Instruction->HasModRM);
3908 				if (!Decode) continue;
3909 				Instruction->Groups |= ITYPE_SYSTEM;
3910 				Instruction->NeedsEmulation = TRUE;
3911 				Operand->Flags |= OP_REG;
3912 				switch (X86Instruction->OperandSize)
3913 				{
3914 					case 8:
3915 					case 4:
3916 					case 2:
3917 						Operand->Register = X86_TEST_OFFSET + rex_modrm.reg;
3918 						break;
3919 					default:
3920 						assert(0);
3921 						return NULL;
3922 				}
3923 
3924 				X86_SET_REG(0);
3925 				if (Disassemble)
3926 				{
3927 					APPENDS(X86_Registers[Operand->Register]);
3928 					X86_WRITE_OPFLAGS();
3929 				}
3930 				//DISASM_OUTPUT(("[SetOperand] AMODE_T (test register)\n"));
3931 				continue;
3932 
3933 			case AMODE_C: // modrm.reg = control register
3934 				assert(X86Instruction->HasModRM);
3935 				assert(Instruction->Type == ITYPE_MOV);
3936 				if (!Decode) continue;
3937 				Instruction->Groups |= ITYPE_SYSTEM;
3938 				Instruction->NeedsEmulation = TRUE;
3939 				Operand->Flags |= OP_REG;
3940 				if (IS_AMD64()) X86Instruction->OperandSize = 8;
3941 				switch (X86Instruction->OperandSize)
3942 				{
3943 					case 8:
3944 					case 4:
3945 					case 2:
3946 						Operand->Register = X86_CONTROL_OFFSET + rex_modrm.reg;
3947 						break;
3948 					default:
3949 						assert(0);
3950 						return NULL;
3951 				}
3952 
3953 				X86_SET_REG(0);
3954 				if (Disassemble)
3955 				{
3956 					APPENDS(X86_Registers[Operand->Register]);
3957 					X86_WRITE_OPFLAGS();
3958 				}
3959 				//DISASM_OUTPUT(("[SetOperand] AMODE_C (control register)\n"));
3960 				continue;
3961 
3962 			case AMODE_D: // modrm.reg = debug register
3963 				assert(X86Instruction->HasModRM);
3964 				assert(Instruction->Type == ITYPE_MOV);
3965 				if (!Decode) continue;
3966 				Instruction->NeedsEmulation = TRUE;
3967 				Operand->Flags |= OP_REG;
3968 				Instruction->Groups |= ITYPE_SYSTEM;
3969 				Instruction->NeedsEmulation = TRUE;
3970 				if (IS_AMD64()) X86Instruction->OperandSize = 8;
3971 				switch (X86Instruction->OperandSize)
3972 				{
3973 					case 8:
3974 					case 4:
3975 					case 2:
3976 						Operand->Register = X86_DEBUG_OFFSET + rex_modrm.reg;
3977 						break;
3978 					default:
3979 						assert(0);
3980 						return NULL;
3981 				}
3982 
3983 				X86_SET_REG(0);
3984 				if (Disassemble)
3985 				{
3986 					APPENDS(X86_Registers[Operand->Register]);
3987 					X86_WRITE_OPFLAGS();
3988 				}
3989 				//DISASM_OUTPUT(("[SetOperand] AMODE_D (debug register)\n"));
3990 				continue;
3991 
3992 			////////////////////////////////////////////////////////////
3993 			// Mod R/M byte with memory or register
3994 			////////////////////////////////////////////////////////////
3995 
3996 			case AMODE_M: // memory only
3997 				assert(X86Instruction->HasModRM);
3998 				if (modrm.mod == 3)
3999 				{
4000 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod = 3 for AMODE_M (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
4001 					goto abort;
4002 				}
4003 				assert(X86Instruction->Segment == SEG_DS || X86Instruction->HasSegmentOverridePrefix);
4004 				//DISASM_OUTPUT(("[SetOperand] AMODE_M (memory only)\n"));
4005 				Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
4006 				if (!Address) return NULL;
4007 				break;
4008 
4009 			case AMODE_E: // general register or memory
4010 				assert(X86Instruction->HasModRM);
4011 				if (OperandType == OPTYPE_p && modrm.mod == 3)
4012 				{
4013 					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod = 3 for AMODE_E with OPTYPE_p (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
4014 					goto abort;
4015 				}
4016 
4017 				//DISASM_OUTPUT(("[SetOperand] AMODE_E (general register or memory)\n"));
4018 				Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
4019 				if (!Address) return NULL;
4020 				if (Decode && (Instruction->Type == ITYPE_PUSH || Instruction->Type == ITYPE_POP))
4021 				{
4022 					assert(X86Instruction->OperandSize >= Operand->Length);
4023 					Operand->Length = X86Instruction->OperandSize;
4024 				}
4025 				break;
4026 
4027 			case AMODE_Q: // mmx register or memory address
4028 				assert(X86Instruction->HasModRM);
4029 				//DISASM_OUTPUT(("[SetOperand] AMODE_Q (MMX register or memory address)\n"));
4030 				if (modrm.mod == 3) // it is a register
4031 				{
4032 					if (rex_modrm.rm > 7)
4033 					{
4034 						if (!SuppressErrors) printf("[0x%08I64X] ERROR: invalid mmx register %d for AMODE_P (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.rm, X86Instruction->Opcode.Mnemonic);
4035 						goto abort;
4036 					}
4037 					Operand->Register = X86_MMX_OFFSET + rex_modrm.rm;
4038 					Operand->Flags |= OP_REG;
4039 					X86_SET_REG(0);
4040 				}
4041 				else
4042 				{
4043 					Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
4044 					if (!Address) return NULL;
4045 				}
4046 				break;
4047 
4048 			case AMODE_W: // xmm register or memory address
4049 				assert(X86Instruction->HasModRM);
4050 				//DISASM_OUTPUT(("[SetOperand] AMODE_W (XMM register or memory address)\n"));
4051 				if (modrm.mod == 3) // it is a register
4052 				{
4053 					Operand->Register = X86_XMM_OFFSET + rex_modrm.rm;
4054 					Operand->Flags |= OP_REG;
4055 					X86_SET_REG(0);
4056 				}
4057 				else
4058 				{
4059 					Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
4060 					if (!Address) return NULL;
4061 				}
4062 				break;
4063 
4064 			default:
4065 				assert(0);
4066 				return NULL;
4067 		}
4068 
4069 		if (!Decode) continue;
4070 
4071 		// If this is reached then SetModRM32 was called
4072 		if ((Operand->Flags & OP_ADDRESS))
4073 		{
4074 			assert(Operand->Length);
4075 			switch (Operand->Register)
4076 			{
4077 				case X86_REG_BP:
4078 				case X86_REG_EBP:
4079 				case AMD64_REG_RBP:
4080 					if (X86Instruction->Displacement > 0) Operand->Flags |= OP_PARAM;
4081 					else Operand->Flags |= OP_LOCAL;
4082 					break;
4083 				default:
4084 					break;
4085 			}
4086 		}
4087 
4088 		if (Disassemble)
4089 		{
4090 			Index = OperandType >> OPTYPE_SHIFT;
4091 			assert(Index > 0 && Index < MAX_OPTYPE_INDEX && OptypeHandlers[Index]);
4092 			OptypeHandlers[Index](Instruction, Operand, OperandIndex);
4093 			X86_WRITE_OPFLAGS();
4094 		}
4095 	}
4096 
4097 	return Address;
4098 
4099 abort:
4100 	if (!SuppressErrors)
4101 	{
4102 #ifdef TEST_DISASM
4103 		printf("Dump of 0x%04I64X:\n", VIRTUAL_ADDRESS);
4104 		__try { DumpAsBytes(stdout, Instruction->Address, (ULONG_PTR)VIRTUAL_ADDRESS, 16, TRUE); }
4105 		__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {}
4106 #endif
4107 		fflush(stdout);
4108 	}
4109 	return NULL;
4110 }
4111 
4112 // NOTE: Address points one byte after ModRM
SetModRM16(INSTRUCTION * Instruction,U8 * Address,INSTRUCTION_OPERAND * Operand,U32 OperandIndex,BOOL SuppressErrors)4113 INTERNAL U8 *SetModRM16(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors)
4114 {
4115 	MODRM modrm;
4116 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
4117 
4118 	DISASM_OUTPUT(("[SetModRM16] Current instruction length = %d\n", Instruction->Length));
4119 	modrm = X86Instruction->modrm;
4120 	assert(!X86Instruction->rex_b);
4121 
4122 	//
4123 	// Both operands are registers
4124 	// Condition: mod = 3
4125 	//
4126 	if (modrm.mod == 3)
4127 	{
4128 		//DISASM_OUTPUT(("[SetModRM16] Both regs (rm_reg %d)\n", modrm.rm));
4129 		switch (Operand->Length)
4130 		{
4131 			case 4: Operand->Register = X86_32BIT_OFFSET + modrm.rm; break;
4132 			case 2: Operand->Register = X86_16BIT_OFFSET + modrm.rm; break;
4133 			case 1: Operand->Register = X86_8BIT_OFFSET + modrm.rm; break;
4134 			default: assert(0); return NULL;
4135 		}
4136 		Operand->Flags |= OP_REG;
4137 	}
4138 
4139 	//
4140 	// Address is an absolute address (technically a 16-bit offset from DS:0)
4141 	// Condition: mod = 0 and rm = 6
4142 	//
4143 	else if (modrm.mod == 0 && modrm.rm == 6)
4144 	{
4145 		//DISASM_OUTPUT(("[SetModRM16] Absolute addressing (displacement 0x%04X)\n", *(S16 *)Address));
4146 		X86Instruction->Displacement = (S64)(*((S16 *)Address));
4147 		if (IS_VALID_ADDRESS(X86Instruction->Displacement))
4148 		{
4149 			X86Instruction->HasFullDisplacement = TRUE;
4150 			X86_SET_TARGET();
4151 			Operand->Flags |= OP_GLOBAL;
4152 		}
4153 		X86_SET_ADDR();
4154 		Operand->Flags |= OP_ADDRESS;
4155 		INSTR_INC(2);
4156 	}
4157 
4158 	// Conditions:
4159 	// (1) mod = 0 and rm != 6
4160 	// (2) mod = 1-2 and rm = 0-7
4161 	else
4162 	{
4163 		switch (modrm.mod)
4164 		{
4165 			case 0: // no displacement
4166 				//DISASM_OUTPUT(("[SetModRM16] Indirect addressing (no displacement)\n"));
4167 				break;
4168 			case 1: // 8-bit signed displacement
4169 				//DISASM_OUTPUT(("[SetModRM16] Indirect addressing (displacement = 0x%02X, reg_rm = %d)\n", *(S8 *)Address, modrm.rm));
4170 				X86Instruction->Displacement = (S64)(*((S8 *)Address));
4171 				INSTR_INC(1); // increment Instruction->Length and address
4172 				break;
4173 			case 2: // 16-bit displacement
4174 				//DISASM_OUTPUT(("[SetModRM16] Indirect addressing (displacement = 0x%04X, reg_rm = %d)\n", *(S16 *)Address, modrm.rm));
4175 				X86Instruction->Displacement = (S64)(*((S16 *)Address));
4176 				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
4177 				{
4178 					Operand->Flags |= OP_GLOBAL;
4179 					X86Instruction->HasFullDisplacement = TRUE;
4180 				}
4181 				INSTR_INC(2);
4182 				break;
4183 		}
4184 
4185 		switch (modrm.rm)
4186 		{
4187 			case 0:
4188 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BX+SI]\n"));
4189 				X86Instruction->BaseRegister = X86_REG_BX;
4190 				X86Instruction->IndexRegister = X86_REG_SI;
4191 				X86Instruction->HasIndexRegister = TRUE;
4192 				break;
4193 			case 1:
4194 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BX+DI]\n"));
4195 				X86Instruction->BaseRegister = X86_REG_BX;
4196 				X86Instruction->IndexRegister = X86_REG_DI;
4197 				X86Instruction->HasIndexRegister = TRUE;
4198 				break;
4199 			case 2:
4200 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BP+SI]\n"));
4201 				X86Instruction->BaseRegister = X86_REG_BP;
4202 				X86Instruction->IndexRegister = X86_REG_SI;
4203 				X86Instruction->HasIndexRegister = TRUE;
4204 				X86_SET_SEG(REG_BP);
4205 				break;
4206 			case 3:
4207 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BP+DI]\n"));
4208 				X86Instruction->BaseRegister = X86_REG_BP;
4209 				X86Instruction->IndexRegister = X86_REG_DI;
4210 				X86Instruction->HasIndexRegister = TRUE;
4211 				X86_SET_SEG(REG_BP);
4212 				break;
4213 			case 4:
4214 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [SI]\n"));
4215 				X86Instruction->BaseRegister = X86_REG_SI;
4216 				break;
4217 			case 5:
4218 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [DI]\n"));
4219 				X86Instruction->BaseRegister = X86_REG_DI;
4220 				break;
4221 			case 6:
4222 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BP]\n"));
4223 				X86Instruction->BaseRegister = X86_REG_BP;
4224 				break;
4225 			case 7:
4226 				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BX]\n"));
4227 				X86Instruction->BaseRegister = X86_REG_BX;
4228 				break;
4229 		}
4230 
4231 		X86Instruction->HasBaseRegister = TRUE;
4232 		Operand->Flags |= OP_ADDRESS | OP_REG;
4233 		X86_SET_ADDR();
4234 	}
4235 
4236 	return Address;
4237 }
4238 
4239 // NOTE: Address points one byte after ModRM
SetModRM32(INSTRUCTION * Instruction,U8 * Address,INSTRUCTION_OPERAND * Operand,U32 OperandIndex,BOOL SuppressErrors)4240 INTERNAL U8 *SetModRM32(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors)
4241 {
4242 	MODRM modrm;
4243 	REX_MODRM rex_modrm;
4244 	U32 i, ImmediateSize = 0;
4245 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
4246 
4247 	if (X86Instruction->AddressSize == 2)
4248 	{
4249 		return SetModRM16(Instruction, Address, Operand, OperandIndex, SuppressErrors);
4250 	}
4251 
4252 	//DISASM_OUTPUT(("[SetModRM32] Length %d, modrm = 0x%02X\n", Instruction->Length, X86Instruction->modrm_b));
4253 	modrm = X86Instruction->modrm;
4254 	rex_modrm = X86Instruction->rex_modrm;
4255 
4256 	//
4257 	// Both operands are registers
4258 	// Condition: mod = 3
4259 	//
4260 	if (modrm.mod == 3)
4261 	{
4262 		switch (Operand->Length)
4263 		{
4264 			case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.rm; break;
4265 			case 4: Operand->Register = X86_32BIT_OFFSET + rex_modrm.rm; CHECK_AMD64_REG(); break;
4266 			case 2: Operand->Register = X86_16BIT_OFFSET + rex_modrm.rm; CHECK_AMD64_REG(); break;
4267 			case 1: Operand->Register = X86_8BIT_OFFSET + rex_modrm.rm; if (X86Instruction->rex_b) CHECK_AMD64_REG(); break;
4268 			default: assert(0); return NULL;
4269 		}
4270 		X86_SET_REG(rex_modrm.rm);
4271 		Operand->Flags |= OP_REG;
4272 	}
4273 
4274 	//
4275 	// Address is an absolute address (technically a 32-bit offset from DS:0)
4276 	// mod = 0 and rm = 5
4277 	//
4278 	else if (modrm.mod == 0 && modrm.rm == 5)
4279 	{
4280 		//DISASM_OUTPUT(("[SetModRM32] Absolute addressing (displacement 0x%08lX)\n", *(S32 *)Address));
4281 		Operand->Flags |= OP_ADDRESS;
4282 		X86Instruction->Displacement = (S64)*((S32 *)Address);
4283 		INSTR_INC(4); // increment Instruction->Length and address
4284 
4285 		if (IS_AMD64())
4286 		{
4287 			// RIP-relative addressing always replaced Disp32, even when using a 32-bit address space
4288 			// (via address size override prefix)
4289 			switch (X86Instruction->OperandSize)
4290 			{
4291 				case 8: Operand->Register = AMD64_REG_RIP; break;
4292 				case 4: Operand->Register = X86_REG_EIP; break;
4293 				case 2: Operand->Register = X86_REG_IP; break;
4294 				default: assert(0); return NULL;
4295 			}
4296 			X86Instruction->BaseRegister = Operand->Register;
4297 			X86Instruction->HasBaseRegister = TRUE;
4298 			X86Instruction->Relative = TRUE;
4299 			Operand->Flags |= OP_IPREL | OP_SIGNED | OP_REG;
4300 			SANITY_CHECK_SEGMENT_OVERRIDE();
4301 			if (!X86Instruction->HasSegmentOverridePrefix) X86Instruction->Segment = SEG_CS;
4302 			X86Instruction->HasFullDisplacement = TRUE;
4303 
4304 			// Since there may be an immediate value to follow, it is necessary
4305 			// to determine the length in order get the proper offset
4306 			//
4307 			// Maybe there is a better way to do this, since this is wasteful
4308 			// (the size of the immediate value will have to be decoded again later
4309 			// in SetOperands)
4310 
4311 			for (ImmediateSize = 0, i = OperandIndex+1; i < Instruction->OperandCount; i++)
4312 			{
4313 				if ((X86Instruction->Opcode.OperandFlags[i] & X86_AMODE_MASK) != AMODE_I) continue;
4314 				else assert(!ImmediateSize);
4315 				switch (X86Instruction->Opcode.OperandFlags[i] & X86_OPTYPE_MASK)
4316 				{
4317 					case OPTYPE_v:
4318 						ImmediateSize = X86Instruction->OperandSize;
4319 						break;
4320 					case OPTYPE_z:
4321 						switch (X86Instruction->OperandSize)
4322 						{
4323 							case 8: case 4: ImmediateSize = 4; break;
4324 							case 2: ImmediateSize = 2; break;
4325 							default: assert(0); return NULL;
4326 						}
4327 						break;
4328 					case OPTYPE_b:
4329 						ImmediateSize = 1;
4330 						break;
4331 					case OPTYPE_w:
4332 						ImmediateSize = 2;
4333 						break;
4334 					case OPTYPE_1:
4335 						break;
4336 					default:
4337 						assert(0);
4338 						break;
4339 				}
4340 			}
4341 
4342 			Operand->TargetAddress = ApplyDisplacement((U64)Address + ImmediateSize, Instruction);
4343 		}
4344 		else if (IS_VALID_ADDRESS(X86Instruction->Displacement))
4345 		{
4346 			X86_SET_TARGET();
4347 			Operand->Flags |= OP_GLOBAL;
4348 			X86Instruction->HasFullDisplacement = TRUE;
4349 		}
4350 
4351 		X86_SET_ADDR();
4352 	}
4353 
4354 	//
4355 	// Addressing mode indicated by SIB byte
4356 	// Condition: mod = 0-2 and rm = 4
4357 	//
4358 	else if (modrm.rm == 4)
4359 	{
4360 		// The X86_SET_*() is called from within SetSIB()
4361 		Address = SetSIB(Instruction, Address, Operand, OperandIndex, SuppressErrors);
4362 		if (!Address)
4363 		{
4364 			assert(0);
4365 			return NULL;
4366 		}
4367 
4368 		if (X86Instruction->sib.base != 5) // if base == 5, the displacement is handled in SetSIB
4369 		{
4370 			switch (modrm.mod)
4371 			{
4372 				case 1: // 8-bit displacement
4373 					//DISASM_OUTPUT(("[SetModRM32] After SIB: displacement 0x%02X\n", *((S8 *)Address)));
4374 					X86Instruction->Displacement = (S64)(*((S8 *)Address));
4375 					INSTR_INC(1); // increment Instruction->Length and address
4376 					break;
4377 				case 2: // 32-bit displacement
4378 					//DISASM_OUTPUT(("[SetModRM32] After SIB: displacement 0x%08lX\n", *((S32 *)Address)));
4379 					X86Instruction->Displacement = (S64)*((S32 *)Address);
4380 					if (IS_VALID_ADDRESS(X86Instruction->Displacement))
4381 					{
4382 						Operand->Flags |= OP_GLOBAL;
4383 						X86Instruction->HasFullDisplacement = TRUE;
4384 					}
4385 					INSTR_INC(4); // increment Instruction->Length and address
4386 					break;
4387 			}
4388 		}
4389 	}
4390 
4391 	// Indirect addressing
4392 	// Conditions:
4393 	// (1) mod = 0 and (rm = 0-3 or 6-7)
4394 	// (2) mod = 1-2 and rm != 4
4395 	else
4396 	{
4397 		switch (X86Instruction->AddressSize)
4398 		{
4399 			case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.rm; break;
4400 			case 4: Operand->Register = X86_32BIT_OFFSET + rex_modrm.rm; CHECK_AMD64_REG(); break;
4401 			default: assert(0); return NULL;
4402 		}
4403 		X86Instruction->BaseRegister = Operand->Register;
4404 		X86Instruction->HasBaseRegister = TRUE;
4405 		Operand->Flags |= OP_ADDRESS | OP_REG;
4406 		X86_SET_SEG(rex_modrm.rm);
4407 		X86_SET_ADDR();
4408 
4409 		switch (modrm.mod)
4410 		{
4411 			case 0: // no displacement
4412 				//DISASM_OUTPUT(("[SetModRM32] Indirect addressing (no displacement, reg_rm = %d)\n", rex_modrm.rm));
4413 				break;
4414 			case 1: // 8-bit signed displacement
4415 				//DISASM_OUTPUT(("[SetModRM32] Indirect addressing (displacement = 0x%02X, reg_rm = %d)\n", *(S8 *)Address, rex_modrm.rm));
4416 				X86Instruction->Displacement = (S64)(*((S8 *)Address));
4417 				INSTR_INC(1); // increment Instruction->Length and address
4418 				break;
4419 			case 2: // 32-bit displacement
4420 				//DISASM_OUTPUT(("[SetModRM32] Indirect addressing (displacement = 0x%08lX, reg_rm = %d)\n", *(S32 *)Address, rex_modrm.rm));
4421 				X86Instruction->Displacement = (S64)*((S32 *)Address);
4422 				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
4423 				{
4424 					Operand->Flags |= OP_GLOBAL;
4425 					X86Instruction->HasFullDisplacement = TRUE;
4426 				}
4427 				INSTR_INC(4); // increment Instruction->Length and address
4428 				break;
4429 		}
4430 	}
4431 
4432 	return Address;
4433 }
4434 
4435 // NOTE: Address points at SIB
SetSIB(INSTRUCTION * Instruction,U8 * Address,INSTRUCTION_OPERAND * Operand,U32 OperandIndex,BOOL SuppressErrors)4436 INTERNAL U8 *SetSIB(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors)
4437 {
4438 	REX rex;
4439 	SIB sib;
4440 	REX_SIB rex_sib;
4441 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
4442 
4443 	X86Instruction->sib_b = *Address;
4444 	SET_SIB(X86Instruction->sib, *Address);
4445 	sib = X86Instruction->sib;
4446 	rex = X86Instruction->rex;
4447 	SET_REX_SIB(X86Instruction->rex_sib, rex, sib);
4448 	rex_sib = X86Instruction->rex_sib;
4449 
4450 	//if (!X86Instruction->rex_b) DISASM_OUTPUT(("[0x%08I64X] SIB = 0x%02X (scale=%d, index=%d, base=%d)\n", VIRTUAL_ADDRESS, *Address, sib.scale, sib.index, sib.base)); \
4451 	//else DISASM_OUTPUT(("[0x%08I64X] SIB = 0x%02X (scale=%d, index=%d, base=%d)\n", VIRTUAL_ADDRESS, *Address, sib.scale, rex_sib.index, rex_sib.base)); \
4452 	//DISASM_OUTPUT(("[SetSIB] Current instruction length = %d\n", Instruction->Length));
4453 
4454 	Operand->Flags |= OP_ADDRESS;
4455 	X86_SET_ADDR();
4456 	INSTR_INC(1); // increment Instruction->Length and address
4457 
4458 	if (sib.base == 5)
4459 	{
4460 		switch (X86Instruction->modrm.mod)
4461 		{
4462 			case 0:
4463 				X86Instruction->Displacement = (S64)*((S32 *)Address);
4464 				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
4465 				{
4466 					X86Instruction->HasFullDisplacement = TRUE;
4467 					X86_SET_TARGET();
4468 					Operand->Flags |= OP_GLOBAL;
4469 				}
4470 				INSTR_INC(4);
4471 				break;
4472 			case 1:
4473 				X86Instruction->Displacement = (S64)(*((S8 *)Address));
4474 				if (rex_sib.base == 5)
4475 				{
4476 					switch (X86Instruction->AddressSize)
4477 					{
4478 						case 8: Operand->Register = AMD64_REG_RBP; break;
4479 						case 4: Operand->Register = X86_REG_EBP; break;
4480 						default: assert(0); return NULL;
4481 					}
4482 					X86_SET_SEG(REG_EBP);
4483 				}
4484 				else
4485 				{
4486 					Operand->Register = AMD64_REG_R13;
4487 				}
4488 
4489 				X86Instruction->BaseRegister = Operand->Register;
4490 				X86Instruction->HasBaseRegister = TRUE;
4491 				Operand->Flags |= OP_REG;
4492 				INSTR_INC(1);
4493 				break;
4494 			case 2:
4495 				X86Instruction->Displacement = (S64)*((S32 *)Address);
4496 				if (rex_sib.base == 5)
4497 				{
4498 					switch (X86Instruction->AddressSize)
4499 					{
4500 						case 8: Operand->Register = AMD64_REG_RBP; break;
4501 						case 4: Operand->Register = X86_REG_EBP; break;
4502 						default: assert(0); return NULL;
4503 					}
4504 					X86_SET_SEG(REG_EBP);
4505 				}
4506 				else
4507 				{
4508 					Operand->Register = AMD64_REG_R13;
4509 				}
4510 
4511 				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
4512 				{
4513 					Operand->Flags |= OP_GLOBAL;
4514 					X86Instruction->HasFullDisplacement = TRUE;
4515 				}
4516 				X86Instruction->BaseRegister = Operand->Register;
4517 				X86Instruction->HasBaseRegister = TRUE;
4518 				Operand->Flags |= OP_REG;
4519 				INSTR_INC(4);
4520 				break;
4521 		}
4522 	}
4523 	else
4524 	{
4525 		switch (X86Instruction->AddressSize)
4526 		{
4527 			case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_sib.base; break;
4528 			case 4: Operand->Register = X86_32BIT_OFFSET + rex_sib.base; CHECK_AMD64_REG(); break;
4529 			default: assert(0); return NULL;
4530 		}
4531 		X86Instruction->BaseRegister = Operand->Register;
4532 		X86Instruction->HasBaseRegister = TRUE;
4533 		X86_SET_SEG(rex_sib.base);
4534 		Operand->Flags |= OP_REG;
4535 	}
4536 
4537 	if (rex_sib.index != 4)
4538 	{
4539 		switch (X86Instruction->AddressSize)
4540 		{
4541 			case 8:
4542 				X86Instruction->IndexRegister = AMD64_64BIT_OFFSET + rex_sib.index;
4543 				break;
4544 			case 4:
4545 				X86Instruction->IndexRegister = X86_32BIT_OFFSET + rex_sib.index;
4546 				break;
4547 			default:
4548 				fflush(stdout);
4549 				assert(0);
4550 				return NULL;
4551 		}
4552 
4553 		Operand->TargetAddress = 0;
4554 		X86Instruction->HasIndexRegister = TRUE;
4555 		//DISASM_OUTPUT(("[SetSIB] Index register = %s\n", X86_Registers[X86_32BIT_OFFSET + rex_sib.index]));
4556 
4557 		switch (sib.scale)
4558 		{
4559 			case 0: X86Instruction->Scale = 1; break;
4560 			case 1: X86Instruction->Scale = 2; break;
4561 			case 2: X86Instruction->Scale = 4; break;
4562 			case 3: X86Instruction->Scale = 8; break;
4563 		}
4564 		//DISASM_OUTPUT(("[SetSIB] Scale = %d\n", X86Instruction->Scale));
4565 	}
4566 
4567 	return Address;
4568 }
4569 
ApplyDisplacement(U64 Address,INSTRUCTION * Instruction)4570 INTERNAL U64 ApplyDisplacement(U64 Address, INSTRUCTION *Instruction)
4571 {
4572 	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
4573 
4574 #ifdef SUPPORT_WRAPAROUND
4575 	U64 VirtualAddress = Address + Instruction->VirtualAddressDelta;
4576 	switch (X86Instruction->OperandSize)
4577 	{
4578 		case 8:
4579 		{
4580 			U64 PreAddr = VirtualAddress;
4581 			U64 PostAddr = PreAddr + X86Instruction->Displacement;
4582 			return Address + (PostAddr - PreAddr);
4583 		}
4584 		case 4:
4585 		{
4586 			// We have to do this carefully...
4587 			// If EIP = FFFFF000 and Displacement=2000 then the final IP should be 1000
4588 			// due to wraparound
4589 			U32 PreAddr = (U32)VirtualAddress;
4590 			U32 PostAddr = PreAddr + (S32)X86Instruction->Displacement;
4591 			return Address + (PostAddr - PreAddr);
4592 		}
4593 		case 2:
4594 		{
4595 			// We have to do this carefully...
4596 			// If IP = F000 and Displacement=2000 then the final IP should be 1000
4597 			// due to wraparound
4598 			U16 PreAddr = (U16)VirtualAddress;
4599 			U16 PostAddr = PreAddr + (S16)X86Instruction->Displacement;
4600 			return Address + (PostAddr - PreAddr);
4601 		}
4602 		default:
4603 			assert(0);
4604 			return 0;
4605 	}
4606 #else
4607 	return (Address + X86Instruction->Displacement);
4608 #endif
4609 }
4610 
4611 
4612 
IsValidLockPrefix(X86_INSTRUCTION * X86Instruction,U8 Opcode,U32 OpcodeLength,U8 Group,U8 OpcodeExtension)4613 INTERNAL BOOL IsValidLockPrefix(X86_INSTRUCTION *X86Instruction, U8 Opcode, U32 OpcodeLength, U8 Group, U8 OpcodeExtension)
4614 {
4615 	switch (OpcodeLength)
4616 	{
4617 		case 1:
4618 			switch (X86_LockPrefix_1[Opcode])
4619 			{
4620 				case 0: // instruction can't be locked
4621 					return FALSE;
4622 				case 1: // instruction can be locked
4623 					break;
4624 				case GR:
4625 					assert(Group);
4626 					if (!X86_LockPrefix_Groups[Group-1][OpcodeExtension]) return FALSE;
4627 					break;
4628 				default:
4629 					assert(0);
4630 					return FALSE;
4631 			}
4632 			break;
4633 
4634 		case 2:
4635 		case 3:
4636 			switch (X86_LockPrefix_2[Opcode])
4637 			{
4638 				case 0: // lock prefix is not acceptable
4639 					return FALSE;
4640 				case 1: // lock prefix allowed
4641 					break;
4642 				case GR:
4643 					assert(Group);
4644 					if (!X86_LockPrefix_Groups[Group-1][OpcodeExtension]) return FALSE;
4645 					break;
4646 				default:
4647 					assert(0);
4648 					return FALSE;
4649 			}
4650 			break;
4651 
4652 		default:
4653 			assert(0);
4654 			return FALSE;
4655 	}
4656 
4657 	if (!X86Instruction->HasModRM || X86Instruction->modrm.mod == 3 || !X86Instruction->HasDstAddressing)
4658 	{
4659 		DISASM_OUTPUT(("[0x%08I64X] ERROR: Instruction \"%s\" with LOCK prefix has invalid ModRM addressing\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic, X86Instruction->Instruction->Address));
4660 		return FALSE;
4661 	}
4662 
4663 	return TRUE;
4664 }
4665