Clean up emulator internal error messages
[jpcrr.git] / org / jpc / emulator / memory / codeblock / optimised / RealModeUDecoder.java
blob8991b2152127dec0ba1c6260116dd130bde6fe0e
1 /*
2 JPC-RR: A x86 PC Hardware Emulator
3 Release 1
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009 H. Ilari Liusvaara
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as published by
10 the Free Software Foundation.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 Based on JPC x86 PC Hardware emulator,
22 A project from the Physics Dept, The University of Oxford
24 Details about original JPC can be found at:
26 www-jpc.physics.ox.ac.uk
30 package org.jpc.emulator.memory.codeblock.optimised;
32 import org.jpc.emulator.memory.codeblock.*;
34 import static org.jpc.emulator.memory.codeblock.optimised.MicrocodeSet.*;
36 /**
38 * @author Chris Dennis
40 public final class RealModeUDecoder implements Decoder, InstructionSource
42 private static final boolean[] modrmArray = new boolean[] { // true for opcodes that require a modrm byte
43 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
44 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
45 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
46 true, true, true, true, false, false, false, false, true, true, true, true, false, false, false, false,
48 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
49 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
50 false, false, true, true, false, false, false, false, false, true, false, true, false, false, false, false,
51 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
53 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
54 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
55 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
56 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
58 true, true, false, false, true, true, true, true, false, false, false, false, false, false, false, false,
59 true, true, true, true, false, false, false, false, false, false, false, false, false, false, false, false,
60 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
61 false, false, false, false, false, false, true, true, false, false, false, false, false, false, true, true
64 private static final boolean[] sibArray = new boolean[] { // true for modrm values that require a sib byte (32 bit addressing only)
65 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
66 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
67 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
68 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
70 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
71 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
72 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
73 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
75 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
76 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
77 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
78 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
80 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
81 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
82 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
83 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false
86 private static final boolean[] twoByte_0f_modrmArray = new boolean[] { // true for opcodes that require a modrm byte
87 true, true, true, true, false, false, false, false, false, false, false, true, false, false, false, false,
88 true, true, true, true, true, true, true, true, true, false, false, false, false, false, false, true,
89 true, true, true, true, true, false, true, false, true, true, true, true, true, true, true, true,
90 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
92 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
93 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
94 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
95 true, true, true, true, true, true, true, false, false, false, false, false, true, true, true, true,
97 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
98 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
99 false, false, false, true, true, true, false, false, false, false, false, true, true, true, true, true,
100 true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true,
102 true, true, true, true, true, true, true, true, false, false, false, false, false, false, false, false,
103 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
104 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
105 true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true
108 private static final boolean[] twoByte_0f_sibArray = new boolean[] { // true for modrm values that require a sib byte (32 bit addressing only)
109 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
110 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
111 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
112 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
114 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
115 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
116 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
117 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
119 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
120 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
121 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
122 false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
124 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
125 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
126 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
127 false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false
130 private static final int PREFICES_SG = 0x7;
131 private static final int PREFICES_ES = 0x1;
132 private static final int PREFICES_CS = 0x2;
133 private static final int PREFICES_SS = 0x3;
134 private static final int PREFICES_DS = 0x4;
135 private static final int PREFICES_FS = 0x5;
136 private static final int PREFICES_GS = 0x6;
138 private static final int PREFICES_OPERAND = 0x8;
139 private static final int PREFICES_ADDRESS = 0x10;
141 private static final int PREFICES_REPNE = 0x20;
142 private static final int PREFICES_REPE = 0x40;
144 private static final int PREFICES_REP = PREFICES_REPNE | PREFICES_REPE;
146 private static final int PREFICES_LOCK = 0x80;
148 private ByteSource source;
149 private Operation current;
150 private Operation waiting;
151 private Operation working;
153 private boolean blockComplete;
154 private boolean addressModeDecoded;
156 private int decodeLimit;
158 public RealModeUDecoder()
160 this.current = new Operation();
161 this.waiting = new Operation();
162 this.working = new Operation();
165 public InstructionSource decodeReal(ByteSource source, int limit)
167 reset();
168 this.source = source;
169 decodeLimit = limit;
170 return this;
173 public InstructionSource decodeVirtual8086(ByteSource source, int limit)
175 reset();
176 this.source = source;
177 decodeLimit = limit;
178 return this;
181 public InstructionSource decodeProtected(ByteSource source, boolean operandSize, int limit)
183 return null;
186 private void blockFinished()
188 blockComplete = true;
191 private void rotate()
193 Operation temp = current;
194 current = waiting;
195 waiting = working;
196 working = temp;
199 public boolean getNext()
201 decode(); //will put new block in working
202 rotate(); //moves buffer around
203 if (current.decoded())
204 return true;
205 else if (current.terminal()) {
206 reset();
207 return false;
208 } else
209 return getNext();
212 public void reset()
214 working.reset();
215 waiting.reset();
216 current.reset();
217 blockComplete = false;
220 public int getMicrocode()
222 return current.getMicrocode();
225 public int getLength()
227 return current.getLength();
230 public int getX86Length()
232 return current.getX86Length();
235 private boolean decodingAddressMode()
237 if (addressModeDecoded) {
238 return false;
239 } else {
240 return (addressModeDecoded = true);
244 private void decodeComplete(int position)
246 if (addressModeDecoded) {
247 working.write(MEM_RESET);
248 addressModeDecoded = false;
250 working.finish(position);
253 private void decode()
255 working.reset();
257 if (blockComplete) {
258 working.makeTerminal();
259 return;
262 int length = 0;
263 try {
264 length = decodeOpcode();
265 decodeLimit--;
266 } catch (IllegalStateException e) {
267 if (!waiting.decoded()) {
268 System.err.println("Critical error: Instruction decoding error: " + e);
269 throw e;
271 waiting.write(EIP_UPDATE);
272 working.makeTerminal();
273 blockFinished();
274 return;
277 if (length < 0) {
278 decodeComplete(-length);
279 blockFinished();
280 } else if (decodeLimit <= 0) {
281 decodeComplete(length);
282 working.write(EIP_UPDATE);
283 blockFinished();
284 } else {
285 decodeComplete(length);
289 private int decodeOpcode()
291 int opcode = 0;
292 int opcodePrefix = 0;
293 int prefices = 0;
294 int bytesRead = 0;
295 int modrm = -1;
296 int sib = -1;
298 while (true) {
299 bytesRead += 1;
300 switch (opcode = 0xff & source.getByte()) {
301 case 0x0f:
302 opcodePrefix = (opcodePrefix << 8) | opcode;
303 opcode = 0xff & source.getByte();
304 bytesRead += 1;
305 modrm = opcode;
306 break;
307 case 0xd8:
308 case 0xd9:
309 case 0xda:
310 case 0xdb:
311 case 0xdc:
312 case 0xdd:
313 case 0xde:
314 case 0xdf:
315 opcodePrefix = (opcodePrefix << 8) | opcode;
316 opcode = 0;
317 modrm = 0xff & source.getByte();
318 bytesRead += 1;
319 break;
320 //Prefices
321 case 0x2e:
322 prefices &= ~PREFICES_SG;
323 prefices |= PREFICES_CS;
324 continue;
325 case 0x3e:
326 prefices &= ~PREFICES_SG;
327 prefices |= PREFICES_DS;
328 continue;
329 case 0x26:
330 prefices &= ~PREFICES_SG;
331 prefices |= PREFICES_ES;
332 continue;
333 case 0x36:
334 prefices &= ~PREFICES_SG;
335 prefices |= PREFICES_SS;
336 continue;
337 case 0x64:
338 prefices &= ~PREFICES_SG;
339 prefices |= PREFICES_FS;
340 continue;
341 case 0x65:
342 prefices &= ~PREFICES_SG;
343 prefices |= PREFICES_GS;
344 continue;
345 case 0x66:
346 if ((prefices & PREFICES_OPERAND) != 0)
347 System.err.println("Warning: repeated operand override prefix 0x66 in real mode");
348 //prefices = prefices ^ PREFICES_OPERAND;
349 prefices |= PREFICES_OPERAND;
350 continue;
351 case 0x67:
352 prefices |= PREFICES_ADDRESS;
353 continue;
354 case 0xf2:
355 prefices |= PREFICES_REPNE;
356 continue;
357 case 0xf3:
358 prefices |= PREFICES_REPE;
359 continue;
360 case 0xf0:
361 prefices |= PREFICES_LOCK;
362 continue;
363 default:
364 break;
366 break;
369 opcode = (opcodePrefix << 8) | opcode;
371 switch (opcodePrefix) {
372 case 0x00:
373 if (modrmArray[opcode]) {
374 modrm = 0xff & source.getByte();
375 bytesRead += 1;
376 } else {
377 modrm = -1;
379 if ((modrm == -1) || ((prefices & PREFICES_ADDRESS) == 0)) {
380 sib = -1;
381 } else {
382 if (sibArray[modrm]) {
383 sib = 0xff & source.getByte();
384 bytesRead += 1;
385 } else {
386 sib = -1;
389 break;
390 case 0x0f:
391 if (twoByte_0f_modrmArray[0xff & opcode]) {
392 modrm = 0xff & source.getByte();
393 bytesRead += 1;
394 } else {
395 modrm = -1;
397 if ((modrm == -1) || ((prefices & PREFICES_ADDRESS) == 0)) {
398 sib = -1;
399 } else {
400 if (twoByte_0f_sibArray[modrm]) {
401 sib = 0xff & source.getByte();
402 bytesRead += 1;
403 } else {
404 sib = -1;
407 break;
408 case 0xd8:
409 case 0xd9:
410 case 0xda:
411 case 0xdb:
412 case 0xdc:
413 case 0xdd:
414 case 0xde:
415 case 0xdf:
416 if (sibArray[modrm]) {
417 sib = 0xff & source.getByte();
418 bytesRead += 1;
419 } else {
420 sib = -1;
422 break;
423 default:
424 modrm = -1;
425 sib = -1;
426 break;
429 working.write(INSTRUCTION_START);
431 if (isJump(opcode, modrm))
432 working.write(EIP_UPDATE);
434 int displacement = 0;
436 switch (operationHasDisplacement(prefices, opcode, modrm, sib)) {
437 case 0:
438 break;
439 case 1:
440 displacement = source.getByte();
441 bytesRead += 1;
442 break;
443 case 2:
444 displacement = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00);
445 bytesRead += 2;
446 break;
447 case 4:
448 displacement = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00) | ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000);
449 bytesRead += 4;
450 break;
451 default:
452 System.err.println("Error: " + Integer.valueOf(operationHasDisplacement(prefices, opcode, modrm, sib)) +
453 " byte displacement Invalid.");
454 break;
457 long immediate = 0;
459 switch (operationHasImmediate(prefices, opcode, modrm)) {
460 case 0:
461 break;
462 case 1:
463 immediate = source.getByte();
464 bytesRead += 1;
465 break;
466 case 2:
467 immediate = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00);
468 bytesRead += 2;
469 break;
470 case 3:
471 immediate = ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000) | (source.getByte() & 0xff);
472 bytesRead += 3;
473 break;
474 case 4:
475 immediate = (source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00) | ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000);
476 bytesRead += 4;
477 break;
478 case 6:
479 immediate = 0xffffffffl & ((source.getByte() & 0xff) | ((source.getByte() << 8) & 0xff00) | ((source.getByte() << 16) & 0xff0000) | ((source.getByte() << 24) & 0xff000000));
480 immediate |= ((source.getByte() & 0xffl) | ((source.getByte() << 8) & 0xff00l)) << 32;
481 bytesRead += 6;
482 break;
483 default:
484 System.err.println("Error: " + Integer.valueOf(operationHasImmediate(prefices, opcode, modrm)) +
485 " byte immediate invalid.");
486 break;
489 //write out input operands
490 writeInputOperands(prefices, opcode, modrm, sib, displacement, immediate);
492 //write out calculation
493 writeOperation(prefices, opcode, modrm);
495 //write out output operands
496 writeOutputOperands(prefices, opcode, modrm, sib, displacement);
498 //write out flags
499 writeFlags(prefices, opcode, modrm);
501 if (isJump(opcode, modrm))
502 return -bytesRead;
503 else
504 return bytesRead;
507 private void writeOperation(int prefices, int opcode, int modrm)
509 switch (opcode) {
510 case 0x00: //ADD Eb, Gb
511 case 0x01: //ADD Ev, Gv
512 case 0x02: //ADD Gb, Eb
513 case 0x03: //ADD Gv, Ev
514 case 0x04: //ADD AL, Ib
515 case 0x05: //ADD eAX, Iv
516 case 0xfc0: //XADD Eb, Gb
517 case 0xfc1: working.write(ADD); break; //XADD Ev, Gv
519 case 0x08: //OR Eb, Gb
520 case 0x09: //OR Ev, Gv
521 case 0x0a: //OR Gb, Eb
522 case 0x0b: //OR Gv, Ev
523 case 0x0c: //OR AL, Ib
524 case 0x0d: working.write(OR ); break; //OR eAX, Iv
526 case 0x10: //ADC Eb, Gb
527 case 0x11: //ADC Ev, Gv
528 case 0x12: //ADC Gb, Eb
529 case 0x13: //ADC Gv, Ev
530 case 0x14: //ADC AL, Ib
531 case 0x15: working.write(ADC); break; //ADC eAX, Iv
533 case 0x18: //SBB Eb, Gb
534 case 0x19: //SBB Ev, Gv
535 case 0x1a: //SBB Gb, Eb
536 case 0x1b: //SBB Gv, Ev
537 case 0x1c: //SBB AL, Ib
538 case 0x1d: working.write(SBB); break; //SBB eAX, Iv
540 case 0x20: //AND Eb, Gb
541 case 0x21: //AND Ev, Gv
542 case 0x22: //AND Gb, Eb
543 case 0x23: //AND Gv, Ev
544 case 0x24: //AND AL, Ib
545 case 0x25: //AND eAX, Iv
546 case 0x84: //TEST Eb, Gb
547 case 0x85: //TEST Ev, Gv
548 case 0xa8: //TEST AL, Ib
549 case 0xa9: working.write(AND); break; //TEST eAX, Iv
551 case 0x27: working.write(DAA); break; //DAA
553 case 0x28: //SUB Eb, Gb
554 case 0x29: //SUB Ev, Gv
555 case 0x2a: //SUB Gb, Eb
556 case 0x2b: //SUB Gv, Ev
557 case 0x2c: //SUB AL, Ib
558 case 0x2d: //SUB eAX, Iv
559 case 0x38: //CMP Eb, Gb
560 case 0x39: //CMP Ev, Gv
561 case 0x3a: //CMP Gb, Eb
562 case 0x3b: //CMP Gv, Ev
563 case 0x3c: //CMP AL, Ib
564 case 0x3d: working.write(SUB); break; //CMP eAX, Iv
566 case 0x2f: working.write(DAS); break; //DAS
568 case 0x30: //XOR Eb, Gb
569 case 0x31: //XOR Ev, Gv
570 case 0x32: //XOR Gb, Eb
571 case 0x33: //XOR Gv, Ev
572 case 0x34: //XOR AL, Ib
573 case 0x35: working.write(XOR); break; //XOR eAX, Iv
575 case 0x37: working.write(AAA); break; //AAA
576 case 0x3f: working.write(AAS); break; //AAS
578 case 0x40: //INC eAX
579 case 0x41: //INC eCX
580 case 0x42: //INC eDX
581 case 0x43: //INC eBX
582 case 0x44: //INC eSP
583 case 0x45: //INC eBP
584 case 0x46: //INC eSI
585 case 0x47: working.write(INC); break; //INC eDI
587 case 0x48: //DEC eAX
588 case 0x49: //DEC eCX
589 case 0x4a: //DEC eDX
590 case 0x4b: //DEC eBX
591 case 0x4c: //DEC eSP
592 case 0x4d: //DEC eBP
593 case 0x4e: //DEC eSI
594 case 0x4f: working.write(DEC); break; //DEC eDI
596 case 0x06: //PUSH ES
597 case 0x0e: //PUSH CS
598 case 0x16: //PUSH SS
599 case 0x1e: //PUSH DS
600 case 0x50: //PUSH eAX
601 case 0x51: //PUSH eCX
602 case 0x52: //PUSH eDX
603 case 0x53: //PUSH eBX
604 case 0x54: //PUSH eSP
605 case 0x55: //PUSH eBP
606 case 0x56: //PUSH eSI
607 case 0x57: //PUSH eDI
608 case 0x68: //PUSH Iv
609 case 0x6a: //PUSH Ib
610 case 0xfa0: //PUSH FS
611 case 0xfa8: //PUSH GS
612 switch (prefices & PREFICES_OPERAND) {
613 case 0:
614 working.write(PUSH_O16); break;
615 case PREFICES_OPERAND:
616 working.write(PUSH_O32); break;
618 break;
620 case 0x9c: //PUSHF
621 switch (prefices & PREFICES_OPERAND) {
622 case 0:
623 working.write(PUSHF_O16); break;
624 case PREFICES_OPERAND:
625 working.write(PUSHF_O32); break;
627 break;
629 case 0x07: //POP ES
630 case 0x17: //POP SS
631 case 0x1f: //POP DS
632 case 0x58: //POP eAX
633 case 0x59: //POP eCX
634 case 0x5a: //POP eDX
635 case 0x5b: //POP eBX
636 case 0x5c: //POP eSP
637 case 0x5d: //POP eBP
638 case 0x5e: //POP eSI
639 case 0x5f: //POP eDI
640 case 0x8f: //POP Ev
641 case 0xfa1: //POP FS
642 case 0xfa9: //POP GS
643 switch (prefices & PREFICES_OPERAND) {
644 case 0:
645 working.write(POP_O16); break;
646 case PREFICES_OPERAND:
647 working.write(POP_O32); break;
648 case PREFICES_ADDRESS:
650 break;
652 case 0x9d: //POPF
653 switch (prefices & PREFICES_OPERAND) {
654 case 0:
655 working.write(POPF_O16); break;
656 case PREFICES_OPERAND:
657 working.write(POPF_O32); break;
659 break;
661 case 0x60: //PUSHA/D
662 switch (prefices & PREFICES_OPERAND) {
663 case 0:
664 working.write(PUSHA); break;
665 case PREFICES_OPERAND:
666 working.write(PUSHAD); break;
668 break;
670 case 0x61: //POPA/D
671 switch (prefices & PREFICES_OPERAND) {
672 case 0:
673 working.write(POPA); break;
674 case PREFICES_OPERAND:
675 working.write(POPAD); break;
677 break;
679 case 0x62: //BOUND
680 if ((prefices & PREFICES_OPERAND) != 0)
681 working.write(BOUND_O32);
682 else
683 working.write(BOUND_O16);
684 break;
686 case 0x69: //IMUL Gv, Ev, Iv
687 case 0x6b: //IMUL Gv, Ev, Ib
688 case 0xfaf: //IMUL Gv, Ev
689 if ((prefices & PREFICES_OPERAND) != 0)
690 working.write(IMUL_O32);
691 else
692 working.write(IMUL_O16);
693 break;
695 case 0x6c: //INSB
696 if ((prefices & PREFICES_REP) != 0) {
697 if ((prefices & PREFICES_ADDRESS) != 0)
698 working.write(REP_INSB_A32);
699 else
700 working.write(REP_INSB_A16);
701 } else {
702 if ((prefices & PREFICES_ADDRESS) != 0)
703 working.write(INSB_A32);
704 else
705 working.write(INSB_A16);
707 break;
709 case 0x6d: //INSW/D
710 if ((prefices & PREFICES_OPERAND) != 0) {
711 if ((prefices & PREFICES_REP) != 0) {
712 if ((prefices & PREFICES_ADDRESS) != 0)
713 working.write(REP_INSD_A32);
714 else
715 working.write(REP_INSD_A16);
716 } else {
717 if ((prefices & PREFICES_ADDRESS) != 0)
718 working.write(INSD_A32);
719 else
720 working.write(INSD_A16);
722 } else {
723 if ((prefices & PREFICES_REP) != 0) {
724 if ((prefices & PREFICES_ADDRESS) != 0)
725 working.write(REP_INSW_A32);
726 else
727 working.write(REP_INSW_A16);
728 } else {
729 if ((prefices & PREFICES_ADDRESS) != 0)
730 working.write(INSW_A32);
731 else
732 working.write(INSW_A16);
735 break;
737 case 0x6e: //OUTSB
738 if ((prefices & PREFICES_REP) != 0) {
739 if ((prefices & PREFICES_ADDRESS) != 0)
740 working.write(REP_OUTSB_A32);
741 else
742 working.write(REP_OUTSB_A16);
743 } else {
744 if ((prefices & PREFICES_ADDRESS) != 0)
745 working.write(OUTSB_A32);
746 else
747 working.write(OUTSB_A16);
749 break;
751 case 0x6f: //OUTS DX, Xv
752 if ((prefices & PREFICES_OPERAND) != 0) {
753 if ((prefices & PREFICES_REP) != 0) {
754 if ((prefices & PREFICES_ADDRESS) != 0)
755 working.write(REP_OUTSD_A32);
756 else
757 working.write(REP_OUTSD_A16);
758 } else {
759 if ((prefices & PREFICES_ADDRESS) != 0)
760 working.write(OUTSD_A32);
761 else
762 working.write(OUTSD_A16);
764 } else {
765 if ((prefices & PREFICES_REP) != 0) {
766 if ((prefices & PREFICES_ADDRESS) != 0)
767 working.write(REP_OUTSW_A32);
768 else
769 working.write(REP_OUTSW_A16);
770 } else {
771 if ((prefices & PREFICES_ADDRESS) != 0)
772 working.write(OUTSW_A32);
773 else
774 working.write(OUTSW_A16);
777 break;
779 case 0x70: working.write(JO_O8); break; //JC Jb
780 case 0x71: working.write(JNO_O8); break; //JNC Jb
781 case 0x72: working.write(JC_O8); break; //JC Jb
782 case 0x73: working.write(JNC_O8); break; //JNC Jb
783 case 0x74: working.write(JZ_O8); break; //JZ Jb
784 case 0x75: working.write(JNZ_O8); break; //JNZ Jb
785 case 0x76: working.write(JNA_O8); break; //JNA Jb
786 case 0x77: working.write(JA_O8); break; //JA Jb
787 case 0x78: working.write(JS_O8); break; //JS Jb
788 case 0x79: working.write(JNS_O8); break; //JNS Jb
789 case 0x7a: working.write(JP_O8); break; //JP Jb
790 case 0x7b: working.write(JNP_O8); break; //JNP Jb
791 case 0x7c: working.write(JL_O8); break; //JL Jb
792 case 0x7d: working.write(JNL_O8); break; //JNL Jb
793 case 0x7e: working.write(JNG_O8); break; //JNG Jb
794 case 0x7f: working.write(JG_O8); break; //JG Jb
796 case 0x80: //IMM GP1 Eb, Ib
797 case 0x81: //IMM GP1 Ev, Iv
798 case 0x82: //IMM GP1 Eb, Ib
799 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
800 switch (modrm & 0x38) {
801 case 0x00:
802 working.write(ADD); break;
803 case 0x08:
804 working.write(OR); break;
805 case 0x10:
806 working.write(ADC); break;
807 case 0x18:
808 working.write(SBB); break;
809 case 0x20:
810 working.write(AND); break;
811 case 0x28:
812 case 0x38: //CMP
813 working.write(SUB); break;
814 case 0x30:
815 working.write(XOR); break;
817 break;
819 case 0x98: //CBW/CWDE
820 if ((prefices & PREFICES_OPERAND) != 0) {
821 working.write(LOAD0_AX);
822 working.write(SIGN_EXTEND_16_32);
823 working.write(STORE0_EAX);
824 } else {
825 working.write(LOAD0_AL);
826 working.write(SIGN_EXTEND_8_16);
827 working.write(STORE0_AX);
829 break;
831 case 0x99:
832 if ((prefices & PREFICES_OPERAND) != 0)
833 working.write(CDQ);
834 else
835 working.write(CWD);
836 break;
838 case 0x9a: //CALLF
839 switch (prefices & PREFICES_OPERAND) {
840 case 0:
841 working.write(CALL_FAR_O16); break;
842 case PREFICES_OPERAND:
843 working.write(CALL_FAR_O32); break;
845 break;
847 case 0x9b: working.write(FWAIT); break; //FWAIT
849 case 0x9e: working.write(SAHF); break;
850 case 0x9f: working.write(LAHF); break;
852 case 0xa4: //MOVSB
853 if ((prefices & PREFICES_REP) != 0) {
854 if ((prefices & PREFICES_ADDRESS) != 0)
855 working.write(REP_MOVSB_A32);
856 else
857 working.write(REP_MOVSB_A16);
858 } else {
859 if ((prefices & PREFICES_ADDRESS) != 0)
860 working.write(MOVSB_A32);
861 else
862 working.write(MOVSB_A16);
864 break;
866 case 0xa5: //MOVSW/D
867 if ((prefices & PREFICES_OPERAND) != 0) {
868 if ((prefices & PREFICES_REP) != 0) {
869 if ((prefices & PREFICES_ADDRESS) != 0)
870 working.write(REP_MOVSD_A32);
871 else
872 working.write(REP_MOVSD_A16);
873 } else {
874 if ((prefices & PREFICES_ADDRESS) != 0)
875 working.write(MOVSD_A32);
876 else
877 working.write(MOVSD_A16);
879 } else {
880 if ((prefices & PREFICES_REP) != 0) {
881 if ((prefices & PREFICES_ADDRESS) != 0)
882 working.write(REP_MOVSW_A32);
883 else
884 working.write(REP_MOVSW_A16);
885 } else {
886 if ((prefices & PREFICES_ADDRESS) != 0)
887 working.write(MOVSW_A32);
888 else
889 working.write(MOVSW_A16);
892 break;
894 case 0xa6: //CMPSB
895 if ((prefices & PREFICES_REPE) != 0) {
896 if ((prefices & PREFICES_ADDRESS) != 0)
897 working.write(REPE_CMPSB_A32);
898 else
899 working.write(REPE_CMPSB_A16);
900 } else if ((prefices & PREFICES_REPNE) != 0) {
901 if ((prefices & PREFICES_ADDRESS) != 0)
902 working.write(REPNE_CMPSB_A32);
903 else
904 working.write(REPNE_CMPSB_A16);
905 } else {
906 if ((prefices & PREFICES_ADDRESS) != 0)
907 working.write(CMPSB_A32);
908 else
909 working.write(CMPSB_A16);
911 break;
913 case 0xa7: //CMPSW/D
914 if ((prefices & PREFICES_OPERAND) != 0) {
915 if ((prefices & PREFICES_REPE) != 0) {
916 if ((prefices & PREFICES_ADDRESS) != 0)
917 working.write(REPE_CMPSD_A32);
918 else
919 working.write(REPE_CMPSD_A16);
920 } else if ((prefices & PREFICES_REPNE) != 0) {
921 if ((prefices & PREFICES_ADDRESS) != 0)
922 working.write(REPNE_CMPSD_A32);
923 else
924 working.write(REPNE_CMPSD_A16);
925 } else {
926 if ((prefices & PREFICES_ADDRESS) != 0)
927 working.write(CMPSD_A32);
928 else
929 working.write(CMPSD_A16);
931 } else {
932 if ((prefices & PREFICES_REPE) != 0) {
933 if ((prefices & PREFICES_ADDRESS) != 0)
934 working.write(REPE_CMPSW_A32);
935 else
936 working.write(REPE_CMPSW_A16);
937 } else if ((prefices & PREFICES_REPNE) != 0) {
938 if ((prefices & PREFICES_ADDRESS) != 0)
939 working.write(REPNE_CMPSW_A32);
940 else
941 working.write(REPNE_CMPSW_A16);
942 } else {
943 if ((prefices & PREFICES_ADDRESS) != 0)
944 working.write(CMPSW_A32);
945 else
946 working.write(CMPSW_A16);
949 break;
951 case 0xaa: //STOSB
952 if ((prefices & PREFICES_REP) != 0) {
953 if ((prefices & PREFICES_ADDRESS) != 0)
954 working.write(REP_STOSB_A32);
955 else
956 working.write(REP_STOSB_A16);
957 } else {
958 if ((prefices & PREFICES_ADDRESS) != 0)
959 working.write(STOSB_A32);
960 else
961 working.write(STOSB_A16);
963 break;
965 case 0xab: //STOSW/STOSD
966 if ((prefices & PREFICES_OPERAND) != 0) {
967 if ((prefices & PREFICES_REP) != 0) {
968 if ((prefices & PREFICES_ADDRESS) != 0)
969 working.write(REP_STOSD_A32);
970 else
971 working.write(REP_STOSD_A16);
972 } else {
973 if ((prefices & PREFICES_ADDRESS) != 0)
974 working.write(STOSD_A32);
975 else
976 working.write(STOSD_A16);
978 } else {
979 if ((prefices & PREFICES_REP) != 0) {
980 if ((prefices & PREFICES_ADDRESS) != 0)
981 working.write(REP_STOSW_A32);
982 else
983 working.write(REP_STOSW_A16);
984 } else {
985 if ((prefices & PREFICES_ADDRESS) != 0)
986 working.write(STOSW_A32);
987 else
988 working.write(STOSW_A16);
991 break;
993 case 0xac: //LODSB
994 if ((prefices & PREFICES_REP) != 0) {
995 if ((prefices & PREFICES_ADDRESS) != 0)
996 working.write(REP_LODSB_A32);
997 else
998 working.write(REP_LODSB_A16);
999 } else {
1000 if ((prefices & PREFICES_ADDRESS) != 0)
1001 working.write(LODSB_A32);
1002 else
1003 working.write(LODSB_A16);
1005 break;
1007 case 0xad: //LODSW/LODSD
1008 if ((prefices & PREFICES_OPERAND) != 0) {
1009 if ((prefices & PREFICES_REP) != 0) {
1010 if ((prefices & PREFICES_ADDRESS) != 0)
1011 working.write(REP_LODSD_A32);
1012 else
1013 working.write(REP_LODSD_A16);
1014 } else {
1015 if ((prefices & PREFICES_ADDRESS) != 0)
1016 working.write(LODSD_A32);
1017 else
1018 working.write(LODSD_A16);
1020 } else {
1021 if ((prefices & PREFICES_REP) != 0) {
1022 if ((prefices & PREFICES_ADDRESS) != 0)
1023 working.write(REP_LODSW_A32);
1024 else
1025 working.write(REP_LODSW_A16);
1026 } else {
1027 if ((prefices & PREFICES_ADDRESS) != 0)
1028 working.write(LODSW_A32);
1029 else
1030 working.write(LODSW_A16);
1033 break;
1035 case 0xae: //SCASB
1036 if ((prefices & PREFICES_REPE) != 0) {
1037 if ((prefices & PREFICES_ADDRESS) != 0)
1038 working.write(REPE_SCASB_A32);
1039 else
1040 working.write(REPE_SCASB_A16);
1041 } else if ((prefices & PREFICES_REPNE) != 0) {
1042 if ((prefices & PREFICES_ADDRESS) != 0)
1043 working.write(REPNE_SCASB_A32);
1044 else
1045 working.write(REPNE_SCASB_A16);
1046 } else {
1047 if ((prefices & PREFICES_ADDRESS) != 0)
1048 working.write(SCASB_A32);
1049 else
1050 working.write(SCASB_A16);
1052 break;
1054 case 0xaf: //SCASW/D
1055 if ((prefices & PREFICES_OPERAND) != 0) {
1056 if ((prefices & PREFICES_REPE) != 0) {
1057 if ((prefices & PREFICES_ADDRESS) != 0)
1058 working.write(REPE_SCASD_A32);
1059 else
1060 working.write(REPE_SCASD_A16);
1061 } else if ((prefices & PREFICES_REPNE) != 0) {
1062 if ((prefices & PREFICES_ADDRESS) != 0)
1063 working.write(REPNE_SCASD_A32);
1064 else
1065 working.write(REPNE_SCASD_A16);
1066 } else {
1067 if ((prefices & PREFICES_ADDRESS) != 0)
1068 working.write(SCASD_A32);
1069 else
1070 working.write(SCASD_A16);
1072 } else {
1073 if ((prefices & PREFICES_REPE) != 0) {
1074 if ((prefices & PREFICES_ADDRESS) != 0)
1075 working.write(REPE_SCASW_A32);
1076 else
1077 working.write(REPE_SCASW_A16);
1078 } else if ((prefices & PREFICES_REPNE) != 0) {
1079 if ((prefices & PREFICES_ADDRESS) != 0)
1080 working.write(REPNE_SCASW_A32);
1081 else
1082 working.write(REPNE_SCASW_A16);
1083 } else {
1084 if ((prefices & PREFICES_ADDRESS) != 0)
1085 working.write(SCASW_A32);
1086 else
1087 working.write(SCASW_A16);
1090 break;
1092 case 0xc0:
1093 case 0xd0:
1094 case 0xd2:
1095 switch (modrm & 0x38) {
1096 case 0x00:
1097 working.write(ROL_O8); break;
1098 case 0x08:
1099 working.write(ROR_O8); break;
1100 case 0x10:
1101 working.write(RCL_O8); break;
1102 case 0x18:
1103 working.write(RCR_O8); break;
1104 case 0x20:
1105 working.write(SHL); break;
1106 case 0x28:
1107 working.write(SHR); break;
1108 case 0x30:
1109 System.err.println("Emulated: invalid SHL encoding");
1110 working.write(SHL); break;
1111 case 0x38:
1112 working.write(SAR_O8); break;
1114 break;
1116 case 0xc1:
1117 case 0xd1:
1118 case 0xd3:
1119 if ((prefices & PREFICES_OPERAND) != 0) {
1120 switch (modrm & 0x38) {
1121 case 0x00:
1122 working.write(ROL_O32); break;
1123 case 0x08:
1124 working.write(ROR_O32); break;
1125 case 0x10:
1126 working.write(RCL_O32); break;
1127 case 0x18:
1128 working.write(RCR_O32); break;
1129 case 0x20:
1130 working.write(SHL); break;
1131 case 0x28:
1132 working.write(SHR); break;
1133 case 0x30:
1134 System.err.println("Emulated: invalid SHL encoding");
1135 working.write(SHL); break;
1136 case 0x38:
1137 working.write(SAR_O32); break;
1139 } else {
1140 switch (modrm & 0x38) {
1141 case 0x00:
1142 working.write(ROL_O16); break;
1143 case 0x08:
1144 working.write(ROR_O16); break;
1145 case 0x10:
1146 working.write(RCL_O16); break;
1147 case 0x18:
1148 working.write(RCR_O16); break;
1149 case 0x20:
1150 working.write(SHL); break;
1151 case 0x28:
1152 working.write(SHR); break;
1153 case 0x30:
1154 System.err.println("Emulated: invalid SHL encoding");
1155 working.write(SHL); break;
1156 case 0x38:
1157 working.write(SAR_O16); break;
1160 break;
1162 case 0xc2:
1163 switch (prefices & PREFICES_OPERAND) {
1164 case 0:
1165 working.write(RET_IW_O16); break;
1166 case PREFICES_OPERAND:
1167 working.write(RET_IW_O32); break;
1169 break;
1171 case 0xc3: //RET
1172 switch (prefices & PREFICES_OPERAND) {
1173 case 0:
1174 working.write(RET_O16); break;
1175 case PREFICES_OPERAND:
1176 working.write(RET_O32); break;
1178 break;
1180 case 0xc8:
1181 switch (prefices & PREFICES_OPERAND) {
1182 case 0:
1183 working.write(ENTER_O16); break;
1184 case PREFICES_OPERAND:
1185 working.write(ENTER_O32); break;
1187 break;
1189 case 0xc9:
1190 switch (prefices & PREFICES_OPERAND) {
1191 case 0:
1192 working.write(LEAVE_O16); break;
1193 case PREFICES_OPERAND:
1194 working.write(LEAVE_O32); break;
1196 break;
1198 case 0xca:
1199 switch (prefices & PREFICES_OPERAND) {
1200 case 0:
1201 working.write(RET_FAR_IW_O16); break;
1202 case PREFICES_OPERAND:
1203 working.write(RET_FAR_IW_O32); break;
1205 break;
1207 case 0xcb:
1208 switch (prefices & PREFICES_OPERAND) {
1209 case 0:
1210 working.write(RET_FAR_O16); break;
1211 case PREFICES_OPERAND:
1212 working.write(RET_FAR_O32); break;
1214 break;
1216 case 0xcc:
1217 switch (prefices & PREFICES_OPERAND) {
1218 case 0:
1219 working.write(INT3_O16); break;
1220 case PREFICES_OPERAND:
1221 working.write(INT3_O32); break;
1223 break;
1225 case 0xcd:
1226 switch (prefices & PREFICES_OPERAND) {
1227 case 0:
1228 working.write(INT_O16); break;
1229 case PREFICES_OPERAND:
1230 working.write(INT_O32); break;
1232 break;
1234 case 0xce:
1235 switch (prefices & PREFICES_OPERAND) {
1236 case 0:
1237 working.write(INTO_O16); break;
1238 case PREFICES_OPERAND:
1239 working.write(INTO_O32); break;
1241 break;
1243 case 0xcf:
1244 switch (prefices & PREFICES_OPERAND) {
1245 case 0:
1246 working.write(IRET_O16); break;
1247 case PREFICES_OPERAND:
1248 working.write(IRET_O32); break;
1250 break;
1252 case 0xd4: working.write(AAM); break; //AAM
1253 case 0xd5: working.write(AAD); break; //AAD
1255 case 0xd6: working.write(SALC); break; //SALC
1257 case 0xe0: //LOOPNZ Jb
1258 if ((prefices & PREFICES_ADDRESS) != 0)
1259 working.write(LOOPNZ_ECX);
1260 else
1261 working.write(LOOPNZ_CX);
1262 break;
1264 case 0xe1: //LOOPZ Jb
1265 if ((prefices & PREFICES_ADDRESS) != 0)
1266 working.write(LOOPZ_ECX);
1267 else
1268 working.write(LOOPZ_CX);
1269 break;
1271 case 0xe2: //LOOP Jb
1272 if ((prefices & PREFICES_ADDRESS) != 0)
1273 working.write(LOOP_ECX);
1274 else
1275 working.write(LOOP_CX);
1276 break;
1278 case 0xe3: //JCXZ
1279 if ((prefices & PREFICES_ADDRESS) != 0)
1280 working.write(JECXZ);
1281 else
1282 working.write(JCXZ);
1283 break;
1285 case 0xe4: //IN AL, Ib
1286 case 0xec: working.write(IN_O8); break; //IN AL, DX
1288 case 0xe5: //IN eAX, Ib
1289 case 0xed: //IN eAX, DX
1290 if ((prefices & PREFICES_OPERAND) != 0)
1291 working.write(IN_O32);
1292 else
1293 working.write(IN_O16);
1294 break;
1296 case 0xe6: //OUT Ib, AL
1297 case 0xee: working.write(OUT_O8); break; //OUT DX, AL
1299 case 0xe7: //OUT Ib, eAX
1300 case 0xef: //OUT DX, eAX
1301 if ((prefices & PREFICES_OPERAND) != 0)
1302 working.write(OUT_O32);
1303 else
1304 working.write(OUT_O16);
1305 break;
1307 case 0xe8: //CALL Jv
1308 switch (prefices & PREFICES_OPERAND) {
1309 case 0:
1310 working.write(CALL_O16); break;
1311 case PREFICES_OPERAND:
1312 working.write(CALL_O32); break;
1314 break;
1316 case 0xe9: //JMP Jv
1317 if ((prefices & PREFICES_OPERAND) != 0)
1318 working.write(JUMP_O32);
1319 else
1320 working.write(JUMP_O16);
1321 break;
1323 case 0xea: //JMPF Ap
1324 if ((prefices & PREFICES_OPERAND) != 0)
1325 working.write(JUMP_FAR_O32);
1326 else
1327 working.write(JUMP_FAR_O16);
1328 break;
1330 case 0xeb: working.write(JUMP_O8); break; //JMP Jb
1332 case 0xf1:
1333 switch (prefices & PREFICES_OPERAND) {
1334 case 0:
1335 working.write(INT1_O16); break;
1336 case PREFICES_OPERAND:
1337 working.write(INT1_O32); break;
1339 break;
1341 case 0xf4: working.write(HALT); break; //HLT
1343 case 0xf5: working.write(CMC); break; //CMC
1345 case 0xf6: //UNA GP3 Eb
1346 switch (modrm & 0x38) {
1347 case 0x00:
1348 working.write(AND); break;
1349 case 0x10:
1350 working.write(NOT); break;
1351 case 0x18:
1352 working.write(NEG); break;
1353 case 0x20:
1354 working.write(MUL_O8); break;
1355 case 0x28:
1356 working.write(IMULA_O8); break;
1357 case 0x30:
1358 working.write(DIV_O8); break;
1359 case 0x38:
1360 working.write(IDIV_O8); break;
1361 default: throw new IllegalStateException("Invalid Gp 3 Instruction F6 /" + ((modrm & 0x38) >> 3) + "?");
1363 break;
1365 case 0xf7: //UNA GP3 Ev
1366 if ((prefices & PREFICES_OPERAND) != 0) {
1367 switch (modrm & 0x38) {
1368 case 0x00:
1369 working.write(AND); break;
1370 case 0x10:
1371 working.write(NOT); break;
1372 case 0x18:
1373 working.write(NEG); break;
1374 case 0x20:
1375 working.write(MUL_O32); break;
1376 case 0x28:
1377 working.write(IMULA_O32); break;
1378 case 0x30:
1379 working.write(DIV_O32); break;
1380 case 0x38:
1381 working.write(IDIV_O32); break;
1382 default: throw new IllegalStateException("Invalid Gp 3 Instruction O32 F7 /" + ((modrm & 0x38) >> 3) + "?");
1384 } else {
1385 switch (modrm & 0x38) {
1386 case 0x00:
1387 working.write(AND); break;
1388 case 0x10:
1389 working.write(NOT); break;
1390 case 0x18:
1391 working.write(NEG); break;
1392 case 0x20:
1393 working.write(MUL_O16); break;
1394 case 0x28:
1395 working.write(IMULA_O16); break;
1396 case 0x30:
1397 working.write(DIV_O16); break;
1398 case 0x38:
1399 working.write(IDIV_O16); break;
1400 default: throw new IllegalStateException("Invalid Gp 3 Instruction O16 F7 /" + ((modrm & 0x38) >> 3) + "?");
1403 break;
1405 case 0xf8: working.write(CLC); break; //CLC
1406 case 0xf9: working.write(STC); break; //STC
1407 case 0xfa: working.write(CLI); break; //CLI
1408 case 0xfb: working.write(STI); break; //STI
1409 case 0xfc: working.write(CLD); break; //CLD
1410 case 0xfd: working.write(STD); break; //STD
1412 case 0xfe:
1413 switch (modrm & 0x38) {
1414 case 0x00: //INC Eb
1415 working.write(INC); break;
1416 case 0x08: //DEC Eb
1417 working.write(DEC); break;
1418 default: throw new IllegalStateException("Invalid Gp 4 Instruction FE /" + ((modrm & 0x38) >> 3) + "?");
1420 break;
1422 case 0xff:
1423 switch (modrm & 0x38) {
1424 case 0x00: //INC Ev
1425 working.write(INC); break;
1426 case 0x08: //DEC Ev
1427 working.write(DEC); break;
1428 case 0x10:
1429 switch (prefices & PREFICES_OPERAND) {
1430 case 0:
1431 working.write(CALL_ABS_O16); break;
1432 case PREFICES_OPERAND:
1433 working.write(CALL_ABS_O32); break;
1435 break;
1436 case 0x18:
1437 switch (prefices & PREFICES_OPERAND) {
1438 case 0:
1439 working.write(CALL_FAR_O16); break;
1440 case PREFICES_OPERAND:
1441 working.write(CALL_FAR_O32); break;
1443 break;
1444 case 0x20:
1445 if ((prefices & PREFICES_OPERAND) != 0)
1446 working.write(JUMP_ABS_O32);
1447 else
1448 working.write(JUMP_ABS_O16);
1449 break;
1450 case 0x28:
1451 if ((prefices & PREFICES_OPERAND) != 0)
1452 working.write(JUMP_FAR_O32);
1453 else
1454 working.write(JUMP_FAR_O16);
1455 break;
1456 case 0x30:
1457 switch (prefices & PREFICES_OPERAND) {
1458 case 0:
1459 working.write(PUSH_O16); break;
1460 case PREFICES_OPERAND:
1461 working.write(PUSH_O32); break;
1463 break;
1464 case 0xff:
1465 working.write(UNDEFINED);
1466 break;
1467 default:
1468 throw new IllegalStateException("Invalid Gp 5 Instruction FF /" + ((modrm & 0x38) >> 3) + "?");
1470 break;
1472 case 0x63: working.write(UNDEFINED); break; //ARPL
1473 case 0x90:
1474 working.write(MEM_RESET); //use mem_reset as Nop
1475 break;
1476 case 0x86: //XCHG Eb, Gb
1477 case 0x87: //XCHG Ev, Gv
1478 case 0x88: //MOV Eb, Gb
1479 case 0x89: //MOV Ev, Gv
1480 case 0x8a: //MOV Gb, Eb
1481 case 0x8b: //MOV Gv, Ev
1482 case 0x8c: //MOV Ew, Sw
1483 case 0x8d: //LEA Gv, M
1484 case 0x8e: //MOV Sw, Ew
1486 case 0x91: //XCHG eAX, eCX
1487 case 0x92: //XCHG eAX, eCX
1488 case 0x93: //XCHG eAX, eCX
1489 case 0x94: //XCHG eAX, eCX
1490 case 0x95: //XCHG eAX, eCX
1491 case 0x96: //XCHG eAX, eCX
1492 case 0x97: //XCHG eAX, eCX
1494 case 0xa0: //MOV AL, Ob
1495 case 0xa1: //MOV eAX, Ov
1496 case 0xa2: //MOV Ob, AL
1497 case 0xa3: //MOV Ov, eAX
1499 case 0xb0: //MOV AL, Ib
1500 case 0xb1: //MOV CL, Ib
1501 case 0xb2: //MOV DL, Ib
1502 case 0xb3: //MOV BL, Ib
1503 case 0xb4: //MOV AH, Ib
1504 case 0xb5: //MOV CH, Ib
1505 case 0xb6: //MOV DH, Ib
1506 case 0xb7: //MOV BH, Ib
1508 case 0xb8: //MOV eAX, Iv
1509 case 0xb9: //MOV eCX, Iv
1510 case 0xba: //MOV eDX, Iv
1511 case 0xbb: //MOV eBX, Iv
1512 case 0xbc: //MOV eSP, Iv
1513 case 0xbd: //MOV eBP, Iv
1514 case 0xbe: //MOV eSI, Iv
1515 case 0xbf: //MOV eDI, Iv
1517 case 0xc4: //LES
1518 case 0xc5: //LDS
1519 case 0xc6: //MOV GP11 Eb, Gb
1520 case 0xc7: //MOV GP11 Ev, Gv
1522 case 0xd7: //XLAT
1523 break;
1525 default:
1526 throw new IllegalStateException("Missing Operation: 0x" + Integer.toHexString(opcode));
1528 //2 Byte Operations
1530 case 0xf00: // Group 6
1531 switch (modrm & 0x38) {
1532 case 0x00:
1533 working.write(SLDT); break;
1534 case 0x08:
1535 working.write(STR); break;
1536 case 0x10:
1537 working.write(LLDT); break;
1538 case 0x18:
1539 working.write(LTR); break;
1540 case 0x20:
1541 working.write(VERR); break;
1542 case 0x28:
1543 working.write(VERW); break;
1544 default: throw new IllegalStateException("Invalid Gp 6 Instruction 0F 00 /" + ((modrm & 0x38) >> 3) + "?");
1545 } break;
1547 case 0xf01:
1548 switch (modrm & 0x38) {
1549 case 0x00:
1550 if ((prefices & PREFICES_OPERAND) != 0)
1551 working.write(SGDT_O32);
1552 else
1553 working.write(SGDT_O16);
1554 break;
1555 case 0x08:
1556 if ((prefices & PREFICES_OPERAND) != 0)
1557 working.write(SIDT_O32);
1558 else
1559 working.write(SIDT_O16);
1560 break;
1561 case 0x10:
1562 if ((prefices & PREFICES_OPERAND) != 0)
1563 working.write(LGDT_O32);
1564 else
1565 working.write(LGDT_O16);
1566 break;
1567 case 0x18:
1568 if ((prefices & PREFICES_OPERAND) != 0)
1569 working.write(LIDT_O32);
1570 else
1571 working.write(LIDT_O16);
1572 break;
1573 case 0x20:
1574 working.write(SMSW); break;
1575 case 0x30:
1576 working.write(LMSW); break;
1577 case 0x38:
1578 working.write(INVLPG); break;
1579 default: throw new IllegalStateException("Invalid Gp 7 Instruction 0F 01 /" + ((modrm & 0x38) >> 3) + "?");
1580 } break;
1582 case 0xf06: working.write(CLTS); break; //CLTS
1583 case 0xf09: working.write(MEM_RESET); break; //WBINVD
1584 case 0xf1f: working.write(MEM_RESET); break; //multi byte NOP (read latest manual)
1585 case 0xf30: working.write(WRMSR); break; //WRMSR
1586 case 0xf31: working.write(RDTSC); break; //RDTSC
1587 case 0xf32: working.write(RDMSR); break; //RDMSR
1589 case 0xf40: working.write(CMOVO); break; //CMOVO
1590 case 0xf41: working.write(CMOVNO); break; //CMOVNO
1591 case 0xf42: working.write(CMOVC); break; //CMOVC
1592 case 0xf43: working.write(CMOVNC); break; //CMOVNC
1593 case 0xf44: working.write(CMOVZ); break; //CMOVZ
1594 case 0xf45: working.write(CMOVNZ); break; //CMOVNZ
1595 case 0xf46: working.write(CMOVNA); break; //CMOVNA
1596 case 0xf47: working.write(CMOVA); break; //CMOVA
1597 case 0xf48: working.write(CMOVS); break; //CMOVS
1598 case 0xf49: working.write(CMOVNS); break; //CMOVNS
1599 case 0xf4a: working.write(CMOVP); break; //CMOVP
1600 case 0xf4b: working.write(CMOVNP); break; //CMOVNP
1601 case 0xf4c: working.write(CMOVL); break; //CMOVL
1602 case 0xf4d: working.write(CMOVNL); break; //CMOVNL
1603 case 0xf4e: working.write(CMOVNG); break; //CMOVNG
1604 case 0xf4f: working.write(CMOVG); break; //CMOVG
1606 case 0xf80: if ((prefices & PREFICES_OPERAND) != 0)
1607 working.write(JO_O32);
1608 else
1609 working.write(JO_O16);
1610 break; //JO Jb
1611 case 0xf81: if ((prefices & PREFICES_OPERAND) != 0)
1612 working.write(JNO_O32);
1613 else
1614 working.write(JNO_O16);
1615 break; //JNO Jb
1616 case 0xf82: if ((prefices & PREFICES_OPERAND) != 0)
1617 working.write(JC_O32);
1618 else
1619 working.write(JC_O16);
1620 break; //JC Jb
1621 case 0xf83: if ((prefices & PREFICES_OPERAND) != 0)
1622 working.write(JNC_O32);
1623 else
1624 working.write(JNC_O16);
1625 break; //JNC Jb
1626 case 0xf84: if ((prefices & PREFICES_OPERAND) != 0)
1627 working.write(JZ_O32);
1628 else
1629 working.write(JZ_O16);
1630 break; //JZ Jb
1631 case 0xf85: if ((prefices & PREFICES_OPERAND) != 0)
1632 working.write(JNZ_O32);
1633 else
1634 working.write(JNZ_O16);
1635 break; //JNZ Jb
1636 case 0xf86: if ((prefices & PREFICES_OPERAND) != 0)
1637 working.write(JNA_O32);
1638 else
1639 working.write(JNA_O16);
1640 break; //JNA Jb
1641 case 0xf87: if ((prefices & PREFICES_OPERAND) != 0)
1642 working.write(JA_O32);
1643 else
1644 working.write(JA_O16);
1645 break; //JA Jb
1646 case 0xf88: if ((prefices & PREFICES_OPERAND) != 0)
1647 working.write(JS_O32);
1648 else
1649 working.write(JS_O16);
1650 break; //JS Jb
1651 case 0xf89: if ((prefices & PREFICES_OPERAND) != 0)
1652 working.write(JNS_O32);
1653 else
1654 working.write(JNS_O16);
1655 break; //JNS Jb
1656 case 0xf8a: if ((prefices & PREFICES_OPERAND) != 0)
1657 working.write(JP_O32);
1658 else
1659 working.write(JP_O16);
1660 break; //JP Jb
1661 case 0xf8b: if ((prefices & PREFICES_OPERAND) != 0)
1662 working.write(JNP_O32);
1663 else
1664 working.write(JNP_O16);
1665 break; //JNP Jb
1666 case 0xf8c: if ((prefices & PREFICES_OPERAND) != 0)
1667 working.write(JL_O32);
1668 else
1669 working.write(JL_O16);
1670 break; //JL Jb
1671 case 0xf8d: if ((prefices & PREFICES_OPERAND) != 0)
1672 working.write(JNL_O32);
1673 else
1674 working.write(JNL_O16);
1675 break; //JNL Jb
1676 case 0xf8e: if ((prefices & PREFICES_OPERAND) != 0)
1677 working.write(JNG_O32);
1678 else
1679 working.write(JNG_O16);
1680 break; //JNG Jb
1681 case 0xf8f: if ((prefices & PREFICES_OPERAND) != 0)
1682 working.write(JG_O32);
1683 else
1684 working.write(JG_O16);
1685 break; //JG Jb
1687 case 0xf90: working.write(SETO); break; //SETO
1688 case 0xf91: working.write(SETNO); break; //SETNO
1689 case 0xf92: working.write(SETC); break; //SETC
1690 case 0xf93: working.write(SETNC); break; //SETNC
1691 case 0xf94: working.write(SETZ); break; //SETZ
1692 case 0xf95: working.write(SETNZ); break; //SETNZ
1693 case 0xf96: working.write(SETNA); break; //SETNA
1694 case 0xf97: working.write(SETA); break; //SETA
1695 case 0xf98: working.write(SETS); break; //SETS
1696 case 0xf99: working.write(SETNS); break; //SETNS
1697 case 0xf9a: working.write(SETP); break; //SETP
1698 case 0xf9b: working.write(SETNP); break; //SETNP
1699 case 0xf9c: working.write(SETL); break; //SETL
1700 case 0xf9d: working.write(SETNL); break; //SETNL
1701 case 0xf9e: working.write(SETNG); break; //SETNG
1702 case 0xf9f: working.write(SETG); break; //SETG
1704 case 0xfa2: working.write(CPUID); break; //CPUID
1706 case 0xfa4: //SHLD Ev, Gv, Ib
1707 case 0xfa5: //SHLD Ev, Gv, CL
1708 if ((prefices & PREFICES_OPERAND) != 0)
1709 working.write(SHLD_O32);
1710 else
1711 working.write(SHLD_O16);
1712 break;
1714 case 0xfac: //SHRD Ev, Gv, Ib
1715 case 0xfad: //SHRD Ev, Gv, CL
1716 if ((prefices & PREFICES_OPERAND) != 0)
1717 working.write(SHRD_O32);
1718 else
1719 working.write(SHRD_O16);
1720 break;
1722 case 0xfb0: //CMPXCHG Eb, Gb
1723 case 0xfb1: //CMPXCHG Ev, Gv
1724 working.write(CMPXCHG); break;
1726 case 0xfa3: //BT Ev, Gv
1727 switch (modrm & 0xc7) {
1728 default: working.write(BT_MEM); break;
1730 case 0xc0:
1731 case 0xc1:
1732 case 0xc2:
1733 case 0xc3:
1734 case 0xc4:
1735 case 0xc5:
1736 case 0xc6:
1737 case 0xc7:
1738 if ((prefices & PREFICES_OPERAND) != 0)
1739 working.write(BT_O32);
1740 else
1741 working.write(BT_O16);
1742 break;
1743 } break;
1745 case 0xfab: //BTS Ev, Gv
1746 switch (modrm & 0xc7) {
1747 default: working.write(BTS_MEM); break;
1749 case 0xc0:
1750 case 0xc1:
1751 case 0xc2:
1752 case 0xc3:
1753 case 0xc4:
1754 case 0xc5:
1755 case 0xc6:
1756 case 0xc7:
1757 if ((prefices & PREFICES_OPERAND) != 0)
1758 working.write(BTS_O32);
1759 else
1760 working.write(BTS_O16);
1761 break;
1762 } break;
1764 case 0xfb3: //BTR Ev, Gv
1765 switch (modrm & 0xc7) {
1766 default: working.write(BTR_MEM); break;
1768 case 0xc0:
1769 case 0xc1:
1770 case 0xc2:
1771 case 0xc3:
1772 case 0xc4:
1773 case 0xc5:
1774 case 0xc6:
1775 case 0xc7:
1776 if ((prefices & PREFICES_OPERAND) != 0)
1777 working.write(BTR_O32);
1778 else
1779 working.write(BTR_O16);
1780 break;
1781 } break;
1783 case 0xfbb: //BTC Ev, Gv
1784 switch (modrm & 0xc7) {
1785 default: working.write(BTC_MEM); break;
1787 case 0xc0:
1788 case 0xc1:
1789 case 0xc2:
1790 case 0xc3:
1791 case 0xc4:
1792 case 0xc5:
1793 case 0xc6:
1794 case 0xc7:
1795 if ((prefices & PREFICES_OPERAND) != 0)
1796 working.write(BTC_O32);
1797 else
1798 working.write(BTC_O16);
1799 break;
1800 } break;
1802 case 0xfba: //Grp 8 Ev, Ib
1803 switch (modrm & 0x38) {
1804 case 0x20:
1805 switch (modrm & 0xc7) {
1806 default: working.write(BT_MEM); break;
1807 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1808 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1809 if ((prefices & PREFICES_OPERAND) != 0)
1810 working.write(BT_O32);
1811 else
1812 working.write(BT_O16);
1813 break;
1814 } break;
1815 case 0x28:
1816 switch (modrm & 0xc7) {
1817 default: working.write(BTS_MEM); break;
1818 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1819 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1820 if ((prefices & PREFICES_OPERAND) != 0)
1821 working.write(BTS_O32);
1822 else
1823 working.write(BTS_O16);
1824 break;
1825 } break;
1826 case 0x30:
1827 switch (modrm & 0xc7) {
1828 default: working.write(BTR_MEM); break;
1829 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1830 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1831 if ((prefices & PREFICES_OPERAND) != 0)
1832 working.write(BTR_O32);
1833 else
1834 working.write(BTR_O16);
1835 break;
1836 } break;
1837 case 0x38:
1838 switch (modrm & 0xc7) {
1839 default: working.write(BTC_MEM); break;
1840 case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1841 case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1842 if ((prefices & PREFICES_OPERAND) != 0)
1843 working.write(BTC_O32);
1844 else
1845 working.write(BTC_O16);
1846 break;
1847 } break;
1848 default: throw new IllegalStateException("Invalid Gp 8 Instruction 0F BA /" + ((modrm & 0x38) >> 3) + "?");
1849 } break;
1851 case 0xfbc: working.write(BSF); break; //BSF Gv, Ev
1852 case 0xfbd: working.write(BSR); break; //BSR Gv, Ev
1854 case 0xfbe: //MOVSX Gv, Eb
1855 if ((prefices & PREFICES_OPERAND) != 0)
1856 working.write(SIGN_EXTEND_8_32);
1857 else
1858 working.write(SIGN_EXTEND_8_16);
1859 break;
1860 case 0xfbf: //MOVSX Gv, Ew
1861 if ((prefices & PREFICES_OPERAND) != 0)
1862 working.write(SIGN_EXTEND_16_32);
1863 break;
1865 case 0xfc8:
1866 case 0xfc9:
1867 case 0xfca:
1868 case 0xfcb:
1869 case 0xfcc:
1870 case 0xfcd:
1871 case 0xfce:
1872 case 0xfcf:
1873 working.write(BSWAP); break;
1875 case 0xf20: //MOV Rd, Cd
1876 case 0xf21: //MOV Rd, Dd
1877 case 0xf22: //MOV Cd, Rd
1878 case 0xf23: //MOV Dd, Rd
1879 case 0xfb2: //LSS Mp
1880 case 0xfb4: //LFS Mp
1881 case 0xfb5: //LGS Mp
1882 case 0xfb6: //MOVZX Gv, Eb
1883 case 0xfb7: //MOVZX Gv, Ew
1884 break;
1886 case 0xd800:
1887 switch (modrm & 0x38)
1889 case 0x00: working.write(FADD); break;
1890 case 0x08: working.write(FMUL); break;
1891 case 0x10:
1892 case 0x18: working.write(FCOM); break;
1893 case 0x20:
1894 case 0x28: working.write(FSUB); break;
1895 case 0x30:
1896 case 0x38: working.write(FDIV); break;
1898 break;
1900 case 0xd900:
1901 if ((modrm & 0xc0) != 0xc0)
1903 switch (modrm & 0x38)
1905 case 0x00: working.write(FPUSH); break;
1906 case 0x10:
1907 case 0x18:
1908 case 0x28:
1909 case 0x38: break;
1910 case 0x20:
1911 if ((prefices & PREFICES_OPERAND) != 0)
1912 working.write(FLDENV_28);
1913 else
1914 working.write(FLDENV_14);
1915 break;
1916 case 0x30:
1917 if ((prefices & PREFICES_OPERAND) != 0)
1918 working.write(FSTENV_28);
1919 else
1920 working.write(FSTENV_14);
1921 break;
1924 else
1926 switch (modrm & 0xf8)
1928 case 0xc0: working.write(FPUSH); break;
1929 case 0xc8: break;
1931 switch (modrm)
1933 case 0xd0: break;
1934 case 0xe0: working.write(FCHS); break;
1935 case 0xe1: working.write(FABS); break;
1936 case 0xe4: working.write(FCOM); break;
1937 case 0xe5: working.write(FXAM); break;
1938 case 0xe8:
1939 case 0xe9:
1940 case 0xea:
1941 case 0xeb:
1942 case 0xec:
1943 case 0xed:
1944 case 0xee: working.write(FPUSH); break;
1945 case 0xf0: working.write(F2XM1); break;
1946 case 0xf1: working.write(FYL2X); break;
1947 case 0xf2: working.write(FPTAN); break;
1948 case 0xf3: working.write(FPATAN); break;
1949 case 0xf4: working.write(FXTRACT); break;
1950 case 0xf5: working.write(FPREM1); break;
1951 case 0xf6: working.write(FDECSTP); break;
1952 case 0xf7: working.write(FINCSTP); break;
1953 case 0xf8: working.write(FPREM); break;
1954 case 0xf9: working.write(FYL2XP1); break;
1955 case 0xfa: working.write(FSQRT); break;
1956 case 0xfb: working.write(FSINCOS); break;
1957 case 0xfc: working.write(FRNDINT); break;
1958 case 0xfd: working.write(FSCALE); break;
1959 case 0xfe: working.write(FSIN); break;
1960 case 0xff: working.write(FCOS); break;
1963 break;
1965 case 0xda00:
1966 if ((modrm & 0xc0) != 0xc0)
1968 switch (modrm & 0x38)
1970 case 0x00: working.write(FADD); break;
1971 case 0x08: working.write(FMUL); break;
1972 case 0x10:
1973 case 0x18: working.write(FCOM); break;
1974 case 0x20:
1975 case 0x28: working.write(FSUB); break;
1976 case 0x30:
1977 case 0x38: working.write(FDIV); break;
1980 else
1982 switch (modrm & 0xf8)
1984 case 0xc0: working.write(FCMOVB); break;
1985 case 0xc8: working.write(FCMOVE); break;
1986 case 0xd0: working.write(FCMOVBE); break;
1987 case 0xd8: working.write(FCMOVU); break;
1989 switch (modrm)
1991 case 0xe9: working.write(FUCOM); break;
1994 break;
1996 case 0xdb00:
1997 if ((modrm & 0xc0) != 0xc0)
1999 switch (modrm & 0x38)
2001 case 0x00: working.write(FPUSH); break;
2002 case 0x08: working.write(FCHOP); break;
2003 case 0x10:
2004 case 0x18: working.write(FRNDINT); break;
2005 case 0x28: working.write(FPUSH); break;
2006 case 0x38: break;
2009 else
2011 switch (modrm & 0xf8)
2013 case 0xc0: working.write(FCMOVNB); break;
2014 case 0xc8: working.write(FCMOVNE); break;
2015 case 0xd0: working.write(FCMOVNBE); break;
2016 case 0xd8: working.write(FCMOVNU); break;
2017 case 0xe8: working.write(FUCOMI); break;
2018 case 0xf0: working.write(FCOMI); break;
2020 switch (modrm)
2022 case 0xe2: working.write(FCLEX); break;
2023 case 0xe3: working.write(FINIT); break;
2024 case 0xe4: break;
2027 break;
2029 case 0xdc00:
2030 switch (modrm & 0x38)
2032 case 0x00: working.write(FADD); break;
2033 case 0x08: working.write(FMUL); break;
2034 case 0x10:
2035 case 0x18: working.write(FCOM); break;
2036 case 0x20:
2037 case 0x28: working.write(FSUB); break;
2038 case 0x30:
2039 case 0x38: working.write(FDIV); break;
2041 break;
2043 case 0xdd00:
2044 if ((modrm & 0xc0) != 0xc0)
2046 switch (modrm & 0x38)
2048 case 0x00: working.write(FPUSH); break;
2049 case 0x08: working.write(FCHOP); break;
2050 case 0x10:
2051 case 0x18:
2052 case 0x38: break;
2053 case 0x20:
2054 if ((prefices & PREFICES_OPERAND) != 0)
2055 working.write(FRSTOR_108);
2056 else
2057 working.write(FRSTOR_94);
2058 break;
2059 case 0x30:
2060 if ((prefices & PREFICES_OPERAND) != 0)
2061 working.write(FSAVE_108);
2062 else
2063 working.write(FSAVE_94);
2064 break;
2067 else
2069 switch (modrm & 0xf8)
2071 case 0xc0: working.write(FFREE); break;
2072 case 0xd0:
2073 case 0xd8: break;
2074 case 0xe0:
2075 case 0xe8: working.write(FUCOM); break;
2078 break;
2080 case 0xde00:
2081 switch (modrm)
2083 case 0xd9: working.write(FCOM); break;
2084 default:
2085 switch (modrm & 0x38)
2087 case 0x00: working.write(FADD); break;
2088 case 0x08: working.write(FMUL); break;
2089 case 0x10:
2090 case 0x18: working.write(FCOM); break;
2091 case 0x20:
2092 case 0x28: working.write(FSUB); break;
2093 case 0x30:
2094 case 0x38: working.write(FDIV); break;
2097 break;
2099 case 0xdf00:
2100 if ((modrm & 0xc0) != 0xc0)
2102 switch (modrm & 0x38)
2104 case 0x00: working.write(FPUSH); break;
2105 case 0x08: working.write(FCHOP); break;
2106 case 0x10:
2107 case 0x18:
2108 case 0x38: working.write(FRNDINT); break;
2109 case 0x20: working.write(FBCD2F); break;
2110 case 0x28: working.write(FPUSH); break;
2111 case 0x30: working.write(FF2BCD); break;
2114 else
2116 switch (modrm & 0xf8)
2118 case 0xe8: working.write(FUCOMI); break;
2119 case 0xf0: working.write(FCOMI); break;
2122 break;
2127 private void writeFlags(int prefices, int opcode, int modrm)
2129 switch (opcode) {
2130 case 0x00: //ADD Eb, Gb
2131 case 0x02: //ADD Gb, Eb
2132 case 0x04: //ADD AL, Ib
2133 case 0xfc0: //XADD Eb, Gb
2134 working.write(ADD_O8_FLAGS); break;
2136 case 0x10: //ADC Eb, Gb
2137 case 0x12: //ADC Gb, Eb
2138 case 0x14: //ADC AL, Ib
2139 working.write(ADC_O8_FLAGS); break;
2141 case 0x18: //SBB Eb, Gb
2142 case 0x1a: //SBB Gb, Eb
2143 case 0x1c: //SBB AL, Ib
2144 working.write(SBB_O8_FLAGS); break;
2146 case 0x28: //SUB Eb, Gb
2147 case 0x2a: //SUB Gb, Eb
2148 case 0x2c: //SUB AL, Ib
2149 case 0x38: //CMP Eb, Gb
2150 case 0x3a: //CMP Gb, Eb
2151 case 0x3c: //CMP AL, Ib
2152 working.write(SUB_O8_FLAGS); break;
2154 case 0x01: //ADD Ev, Gv
2155 case 0x03: //ADD Gv, Ev
2156 case 0x05: //ADD eAX, Iv
2157 case 0xfc1: //XADD Ev, Gv
2158 if ((prefices & PREFICES_OPERAND) != 0)
2159 working.write(ADD_O32_FLAGS);
2160 else
2161 working.write(ADD_O16_FLAGS);
2162 break;
2164 case 0x11: //ADC Ev, Gv
2165 case 0x13: //ADC Gv, Ev
2166 case 0x15: //ADC eAX, Iv
2167 if ((prefices & PREFICES_OPERAND) != 0)
2168 working.write(ADC_O32_FLAGS);
2169 else
2170 working.write(ADC_O16_FLAGS);
2171 break;
2173 case 0x19: //SBB Ev, Gv
2174 case 0x1b: //SBB Gv, Ev
2175 case 0x1d: //SBB eAX, Iv
2176 if ((prefices & PREFICES_OPERAND) != 0)
2177 working.write(SBB_O32_FLAGS);
2178 else
2179 working.write(SBB_O16_FLAGS);
2180 break;
2182 case 0x29: //SUB Ev, Gv
2183 case 0x2b: //SUB Gv, Ev
2184 case 0x2d: //SUB eAX, Iv
2185 case 0x39: //CMP Ev, Gv
2186 case 0x3b: //CMP Gv, Ev
2187 case 0x3d: //CMP eAX, Iv
2188 if ((prefices & PREFICES_OPERAND) != 0)
2189 working.write(SUB_O32_FLAGS);
2190 else
2191 working.write(SUB_O16_FLAGS);
2192 break;
2194 case 0x08: //OR Eb, Gb
2195 case 0x0a: //OR Gb, Eb
2196 case 0x0c: //OR AL, Ib
2197 case 0x20: //AND Eb, Gb
2198 case 0x22: //AND Gb, Eb
2199 case 0x24: //AND AL, Ib
2200 case 0x30: //XOR Eb, Gb
2201 case 0x32: //XOR Gb, Eb
2202 case 0x34: //XOR AL, Ib
2203 case 0x84: //TEST Eb, Gb
2204 case 0xa8: //TEST AL, Ib
2205 working.write(BITWISE_FLAGS_O8); break;
2207 case 0x09: //OR Ev, Gv
2208 case 0x0b: //OR Gv, Ev
2209 case 0x0d: //OR eAX, Iv
2210 case 0x21: //AND Ev, Gv
2211 case 0x23: //AND Gv, Ev
2212 case 0x25: //AND eAX, Iv
2213 case 0x31: //XOR Ev, Gv
2214 case 0x33: //XOR Gv, Ev
2215 case 0x35: //XOR eAX, Iv
2216 case 0x85: //TEST Ev, Gv
2217 case 0xa9: //TEST eAX, Iv
2218 if ((prefices & PREFICES_OPERAND) != 0)
2219 working.write(BITWISE_FLAGS_O32);
2220 else
2221 working.write(BITWISE_FLAGS_O16);
2222 break;
2224 case 0x40: //INC eAX
2225 case 0x41: //INC eCX
2226 case 0x42: //INC eDX
2227 case 0x43: //INC eBX
2228 case 0x44: //INC eSP
2229 case 0x45: //INC eBP
2230 case 0x46: //INC eSI
2231 case 0x47: //INC eDI
2232 if ((prefices & PREFICES_OPERAND) != 0)
2233 working.write(INC_O32_FLAGS);
2234 else
2235 working.write(INC_O16_FLAGS);
2236 break;
2238 case 0x48: //DEC eAX
2239 case 0x49: //DEC eCX
2240 case 0x4a: //DEC eDX
2241 case 0x4b: //DEC eBX
2242 case 0x4c: //DEC eSP
2243 case 0x4d: //DEC eBP
2244 case 0x4e: //DEC eSI
2245 case 0x4f: //DEC eDI
2246 if ((prefices & PREFICES_OPERAND) != 0)
2247 working.write(DEC_O32_FLAGS);
2248 else
2249 working.write(DEC_O16_FLAGS);
2250 break;
2252 case 0x80: //IMM GP1 Eb, Ib
2253 case 0x82: //IMM GP1 Eb, Ib
2254 switch (modrm & 0x38) {
2255 case 0x00:
2256 working.write(ADD_O8_FLAGS); break;
2257 case 0x08:
2258 working.write(BITWISE_FLAGS_O8); break;
2259 case 0x10:
2260 working.write(ADC_O8_FLAGS); break;
2261 case 0x18:
2262 working.write(SBB_O8_FLAGS); break;
2263 case 0x20:
2264 working.write(BITWISE_FLAGS_O8); break;
2265 case 0x28:
2266 case 0x38:
2267 working.write(SUB_O8_FLAGS); break;
2268 case 0x30:
2269 working.write(BITWISE_FLAGS_O8); break;
2271 break;
2273 case 0x81: //IMM GP1 Ev, Iv
2274 case 0x83: //IMM GP1 Ev, Ib (will have been sign extended to short/int)
2275 if ((prefices & PREFICES_OPERAND) != 0) {
2276 switch (modrm & 0x38) {
2277 case 0x00:
2278 working.write(ADD_O32_FLAGS); break;
2279 case 0x08:
2280 working.write(BITWISE_FLAGS_O32); break;
2281 case 0x10:
2282 working.write(ADC_O32_FLAGS); break;
2283 case 0x18:
2284 working.write(SBB_O32_FLAGS); break;
2285 case 0x20:
2286 working.write(BITWISE_FLAGS_O32); break;
2287 case 0x28:
2288 case 0x38:
2289 working.write(SUB_O32_FLAGS); break;
2290 case 0x30:
2291 working.write(BITWISE_FLAGS_O32); break;
2293 } else {
2294 switch (modrm & 0x38) {
2295 case 0x00:
2296 working.write(ADD_O16_FLAGS); break;
2297 case 0x08:
2298 working.write(BITWISE_FLAGS_O16); break;
2299 case 0x10:
2300 working.write(ADC_O16_FLAGS); break;
2301 case 0x18:
2302 working.write(SBB_O16_FLAGS); break;
2303 case 0x20:
2304 working.write(BITWISE_FLAGS_O16); break;
2305 case 0x28:
2306 case 0x38:
2307 working.write(SUB_O16_FLAGS); break;
2308 case 0x30:
2309 working.write(BITWISE_FLAGS_O16); break;
2312 break;
2314 case 0xc0:
2315 case 0xd0:
2316 case 0xd2:
2317 switch (modrm & 0x38) {
2318 case 0x00:
2319 working.write(ROL_O8_FLAGS); break;
2320 case 0x08:
2321 working.write(ROR_O8_FLAGS); break;
2322 case 0x10:
2323 working.write(RCL_O8_FLAGS); break;
2324 case 0x18:
2325 working.write(RCR_O8_FLAGS); break;
2326 case 0x20:
2327 working.write(SHL_O8_FLAGS); break;
2328 case 0x28:
2329 working.write(SHR_O8_FLAGS); break;
2330 case 0x30:
2331 working.write(SHL_O8_FLAGS); break;
2332 case 0x38:
2333 working.write(SAR_O8_FLAGS); break;
2335 break;
2337 case 0xc1:
2338 case 0xd1:
2339 case 0xd3:
2340 if ((prefices & PREFICES_OPERAND) != 0) {
2341 switch (modrm & 0x38) {
2342 case 0x00:
2343 working.write(ROL_O32_FLAGS); break;
2344 case 0x08:
2345 working.write(ROR_O32_FLAGS); break;
2346 case 0x10:
2347 working.write(RCL_O32_FLAGS); break;
2348 case 0x18:
2349 working.write(RCR_O32_FLAGS); break;
2350 case 0x20:
2351 working.write(SHL_O32_FLAGS); break;
2352 case 0x28:
2353 working.write(SHR_O32_FLAGS); break;
2354 case 0x30:
2355 working.write(SHL_O32_FLAGS); break;
2356 case 0x38:
2357 working.write(SAR_O32_FLAGS); break;
2359 } else {
2360 switch (modrm & 0x38) {
2361 case 0x00:
2362 working.write(ROL_O16_FLAGS); break;
2363 case 0x08:
2364 working.write(ROR_O16_FLAGS); break;
2365 case 0x10:
2366 working.write(RCL_O16_FLAGS); break;
2367 case 0x18:
2368 working.write(RCR_O16_FLAGS); break;
2369 case 0x20:
2370 working.write(SHL_O16_FLAGS); break;
2371 case 0x28:
2372 working.write(SHR_O16_FLAGS); break;
2373 case 0x30:
2374 working.write(SHL_O16_FLAGS); break;
2375 case 0x38:
2376 working.write(SAR_O16_FLAGS); break;
2379 break;
2381 case 0xf6: //UNA GP3 Eb
2382 switch (modrm & 0x38) {
2383 case 0x00:
2384 working.write(BITWISE_FLAGS_O8); break;
2385 case 0x18:
2386 working.write(NEG_O8_FLAGS); break;
2388 break;
2390 case 0xf7: //UNA GP3 Ev
2391 if ((prefices & PREFICES_OPERAND) != 0) {
2392 switch (modrm & 0x38) {
2393 case 0x00:
2394 working.write(BITWISE_FLAGS_O32); break;
2395 case 0x18:
2396 working.write(NEG_O32_FLAGS); break;
2398 } else {
2399 switch (modrm & 0x38) {
2400 case 0x00:
2401 working.write(BITWISE_FLAGS_O16); break;
2402 case 0x18:
2403 working.write(NEG_O16_FLAGS); break;
2406 break;
2408 case 0xfe:
2409 switch (modrm & 0x38) {
2410 case 0x00: //INC Eb
2411 working.write(INC_O8_FLAGS); break;
2412 case 0x08: //DEC Eb
2413 working.write(DEC_O8_FLAGS); break;
2415 break;
2417 case 0xff:
2418 switch (modrm & 0x38) {
2419 case 0x00: //INC Eb
2420 if ((prefices & PREFICES_OPERAND) != 0)
2421 working.write(INC_O32_FLAGS);
2422 else
2423 working.write(INC_O16_FLAGS);
2424 break;
2425 case 0x08: //DEC Eb
2426 if ((prefices & PREFICES_OPERAND) != 0)
2427 working.write(DEC_O32_FLAGS);
2428 else
2429 working.write(DEC_O16_FLAGS);
2430 break;
2432 break;
2434 case 0x07: //POP ES
2435 case 0x17: //POP SS
2436 case 0x1f: //POP DS
2437 case 0x58: //POP eAX
2438 case 0x59: //POP eCX
2439 case 0x5a: //POP eDX
2440 case 0x5b: //POP eBX
2441 case 0x5d: //POP eBP
2442 case 0x5e: //POP eSI
2443 case 0x5f: //POP eDI
2444 case 0xfa1: //POP FS
2445 case 0xfa9: working.write(STORE1_ESP); break; //POP GS
2448 case 0x8f: //POP Ev This is really annoying and not quite correct?
2449 for (int i = 0; i < working.getLength(); i++) {
2450 switch (working.getMicrocodeAt(i)) {
2451 case ADDR_SP:
2452 case ADDR_ESP:
2453 working.replace(i, ADDR_REG1);
2454 break;
2455 case ADDR_2ESP:
2456 working.replace(i, ADDR_2REG1);
2457 break;
2458 case ADDR_4ESP:
2459 working.replace(i, ADDR_4REG1);
2460 break;
2461 case ADDR_8ESP:
2462 working.replace(i, ADDR_8REG1);
2463 break;
2464 case ADDR_IB:
2465 case ADDR_IW:
2466 case ADDR_ID:
2467 i++;
2468 break;
2471 switch (working.getMicrocodeAt(working.getLength() - 1)) {
2472 case STORE0_ESP:
2473 case STORE0_SP: break;
2474 default: working.write(STORE1_ESP);
2476 break;
2478 case 0xa6: //CMPSB
2479 if ((prefices & PREFICES_REPE) != 0) {
2480 working.write(REP_SUB_O8_FLAGS);
2481 } else if ((prefices & PREFICES_REPNE) != 0) {
2482 working.write(REP_SUB_O8_FLAGS);
2483 } else {
2484 working.write(SUB_O8_FLAGS);
2486 break;
2488 case 0xa7: //CMPSW/D
2489 if ((prefices & PREFICES_OPERAND) != 0) {
2490 if ((prefices & PREFICES_REPE) != 0) {
2491 working.write(REP_SUB_O32_FLAGS);
2492 } else if ((prefices & PREFICES_REPNE) != 0) {
2493 working.write(REP_SUB_O32_FLAGS);
2494 } else {
2495 working.write(SUB_O32_FLAGS);
2497 } else {
2498 if ((prefices & PREFICES_REPE) != 0) {
2499 working.write(REP_SUB_O16_FLAGS);
2500 } else if ((prefices & PREFICES_REPNE) != 0) {
2501 working.write(REP_SUB_O16_FLAGS);
2502 } else {
2503 working.write(SUB_O16_FLAGS);
2506 break;
2508 case 0xae: //SCASB
2509 if ((prefices & PREFICES_REPE) != 0) {
2510 working.write(REP_SUB_O8_FLAGS);
2511 } else if ((prefices & PREFICES_REPNE) != 0) {
2512 working.write(REP_SUB_O8_FLAGS);
2513 } else {
2514 working.write(SUB_O8_FLAGS);
2516 break;
2518 case 0xaf: //SCASW/D
2519 if ((prefices & PREFICES_OPERAND) != 0) {
2520 if ((prefices & PREFICES_REPE) != 0) {
2521 working.write(REP_SUB_O32_FLAGS);
2522 } else if ((prefices & PREFICES_REPNE) != 0) {
2523 working.write(REP_SUB_O32_FLAGS);
2524 } else {
2525 working.write(SUB_O32_FLAGS);
2527 } else {
2528 if ((prefices & PREFICES_REPE) != 0) {
2529 working.write(REP_SUB_O16_FLAGS);
2530 } else if ((prefices & PREFICES_REPNE) != 0) {
2531 working.write(REP_SUB_O16_FLAGS);
2532 } else {
2533 working.write(SUB_O16_FLAGS);
2536 break;
2540 case 0xcf: //IRET
2541 switch (prefices & PREFICES_OPERAND) {
2542 case 0:
2543 working.write(STORE0_FLAGS); break;
2544 case PREFICES_OPERAND:
2545 working.write(STORE0_EFLAGS); break;
2547 break;
2550 case 0xd4: working.write(BITWISE_FLAGS_O8); break; //AAM
2552 case 0xf1f: break; //NOP
2553 case 0xfa4: //SHLD Ev, Gv, Ib
2554 case 0xfa5: //SHLD Ev, Gv, CL
2555 if ((prefices & PREFICES_OPERAND) != 0)
2556 working.write(SHL_O32_FLAGS);
2557 else
2558 working.write(SHL_O16_FLAGS);
2559 break;
2561 case 0xfac: //SHRD Ev, Gv, Ib
2562 case 0xfad: //SHRD Ev, Gv, CL
2563 if ((prefices & PREFICES_OPERAND) != 0)
2564 working.write(SHR_O32_FLAGS);
2565 else
2566 working.write(SHR_O16_FLAGS);
2567 break;
2569 case 0xfb0: //CMPXCHG Eb, Gb
2570 working.write(CMPXCHG_O8_FLAGS); break;
2571 case 0xfb1: //CMPXCHG Ev, Gv
2572 if ((prefices & PREFICES_OPERAND) != 0)
2573 working.write(CMPXCHG_O32_FLAGS);
2574 else
2575 working.write(CMPXCHG_O16_FLAGS);
2576 break;
2581 case 0x06: //PUSH ES
2582 case 0x0e: //PUSH CS
2584 case 0x16: //PUSH SS
2585 case 0x1e: //PUSH DS
2587 case 0x27: //DAA
2588 case 0x2f: //DAS
2590 case 0x37: //AAA
2591 case 0x3f: //AAS
2593 case 0x50: //PUSH eAX
2594 case 0x51: //PUSH eCX
2595 case 0x52: //PUSH eDX
2596 case 0x53: //PUSH eBX
2597 case 0x54: //PUSH eSP
2598 case 0x55: //PUSH eBP
2599 case 0x56: //PUSH eSI
2600 case 0x57: //PUSH eDI
2601 case 0x5c: //POP eSP so don't write incremented stack pointer back
2603 case 0x60: //PUSHA/D
2604 case 0x61: //POPA/D
2605 case 0x62: //BOUND
2606 case 0x63: //#UD (ARPL)
2607 case 0x68: //PUSH Iv
2608 case 0x69: //IMUL Gv, Ev, Iv
2609 case 0x6a: //PUSH Ib
2610 case 0x6b: //IMUL Gv, Ev, Ib
2611 case 0x6c: //INSB
2612 case 0x6d: //INSW/D
2613 case 0x6e: //OUTSB
2614 case 0x6f: //OUTSW/D
2616 case 0x70: //JO Jb
2617 case 0x71: //JNO Jb
2618 case 0x72: //JC Jb
2619 case 0x73: //JNC Jb
2620 case 0x74: //JZ Jb
2621 case 0x75: //JNZ Jb
2622 case 0x76: //JNA Jb
2623 case 0x77: //JA Jb
2624 case 0x78: //JS Jb
2625 case 0x79: //JNS Jb
2626 case 0x7a: //JP Jb
2627 case 0x7b: //JNP Jb
2628 case 0x7c: //JL Jb
2629 case 0x7d: //JNL Jb
2630 case 0x7e: //JNG Jb
2631 case 0x7f: //JG Jb
2633 case 0x86: //XCHG Eb, Gb
2634 case 0x87: //XCHG Ev, Gv
2635 case 0x88: //MOV Eb, Gb
2636 case 0x89: //MOV Ev, Gv
2637 case 0x8a: //MOV Gb, Eb
2638 case 0x8b: //MOV Gv, Ev
2639 case 0x8c: //MOV Ew, Sw
2640 case 0x8d: //LEA Gv, M
2641 case 0x8e: //MOV Sw, Ew
2643 case 0x90: //NOP
2644 case 0x91: //XCHG eAX, eCX
2645 case 0x92: //XCHG eAX, eCX
2646 case 0x93: //XCHG eAX, eCX
2647 case 0x94: //XCHG eAX, eCX
2648 case 0x95: //XCHG eAX, eCX
2649 case 0x96: //XCHG eAX, eCX
2650 case 0x97: //XCHG eAX, eCX
2651 case 0x98: //CBW/CWDE
2652 case 0x99: //CWD/CDQ
2653 case 0x9a: //CALLF Ap
2654 case 0x9b: //FWAIT
2655 case 0x9c: //PUSHF
2656 case 0x9d: //POPF
2657 case 0x9e: //SAHF
2658 case 0x9f: //LAHF
2660 case 0xa0: //MOV AL, Ob
2661 case 0xa1: //MOV eAX, Ov
2662 case 0xa2: //MOV Ob, AL
2663 case 0xa3: //MOV Ov, eAX
2664 case 0xa4: //MOVSB
2665 case 0xa5: //MOVSW/D
2666 case 0xaa: //STOSB
2667 case 0xab: //STOSW/D
2668 case 0xac: //LODSB
2669 case 0xad: //LODSW/D
2671 case 0xb0: //MOV AL, Ib
2672 case 0xb1: //MOV CL, Ib
2673 case 0xb2: //MOV DL, Ib
2674 case 0xb3: //MOV BL, Ib
2675 case 0xb4: //MOV AH, Ib
2676 case 0xb5: //MOV CH, Ib
2677 case 0xb6: //MOV DH, Ib
2678 case 0xb7: //MOV BH, Ib
2679 case 0xb8: //MOV eAX, Iv
2680 case 0xb9: //MOV eCX, Iv
2681 case 0xba: //MOV eDX, Iv
2682 case 0xbb: //MOV eBX, Iv
2683 case 0xbc: //MOV eSP, Iv
2684 case 0xbd: //MOV eBP, Iv
2685 case 0xbe: //MOV eSI, Iv
2686 case 0xbf: //MOV eDI, Iv
2688 case 0xc2: //RET Iw
2689 case 0xc3: //RET
2690 case 0xc4: //LES
2691 case 0xc5: //LDS
2692 case 0xc6: //MOV GP11 Eb, Gb
2693 case 0xc7: //MOV GP11 Ev, Gv
2694 case 0xc8: //ENTER
2695 case 0xc9: //LEAVE
2696 case 0xca: //RETF Iw
2697 case 0xcb: //RETF
2698 case 0xcc: //INT3
2699 case 0xcd: //INT Ib
2700 case 0xce: //INTO
2702 case 0xd5: //AAD
2703 case 0xd6: //SALC
2704 case 0xd7: //XLAT
2706 case 0xe0: //LOOPNZ
2707 case 0xe1: //LOOPZ
2708 case 0xe2: //LOOP
2709 case 0xe3: //JCXZ
2710 case 0xe4: //IN AL, Ib
2711 case 0xe5: //IN eAX, Ib
2712 case 0xe6: //OUT Ib, AL
2713 case 0xe7: //OUT Ib, eAX
2714 case 0xe8: //CALL Jv
2715 case 0xe9: //JMP Jv
2716 case 0xea: //JMPF Ap
2717 case 0xeb: //JMP Jb
2718 case 0xec: //IN AL, DX
2719 case 0xed: //IN eAX, DX
2720 case 0xee: //OUT DX, AL
2721 case 0xef: //OUT DX, eAX
2723 case 0xf1: //INT1
2725 case 0xf4: //HLT
2726 case 0xf5: //CMC
2727 case 0xf8: //CLC
2728 case 0xf9: //STC
2729 case 0xfa: //CLI
2730 case 0xfb: //STI
2731 case 0xfc: //CLD
2732 case 0xfd: //STD
2734 case 0xf00: //Group 6
2735 case 0xf01: //Group 7
2736 case 0xf06: //CLTS
2737 case 0xf09: //WBINVD
2738 case 0xf20: //MOV Rd, Cd
2739 case 0xf21: //MOV Rd, Dd
2740 case 0xf22: //MOV Cd, Rd
2741 case 0xf23: //MOV Dd, Rd
2742 case 0xf30: //WRMSR
2743 case 0xf31: //RDTSC
2744 case 0xf32: //RDMSR
2745 case 0xf40: //CMOVO
2746 case 0xf41: //CMOVNO
2747 case 0xf42: //CMOVC
2748 case 0xf43: //CMOVNC
2749 case 0xf44: //CMOVZ
2750 case 0xf45: //CMOVNZ
2751 case 0xf46: //CMOVBE
2752 case 0xf47: //CMOVNBE
2753 case 0xf48: //CMOVS
2754 case 0xf49: //CMOVNS
2755 case 0xf4a: //CMOVP
2756 case 0xf4b: //CMOVNP
2757 case 0xf4c: //CMOVL
2758 case 0xf4d: //CMOVNL
2759 case 0xf4e: //CMOVLE
2760 case 0xf4f: //CMOVNLE
2761 case 0xf80: //JO Jv
2762 case 0xf81: //JNO Jv
2763 case 0xf82: //JC Jv
2764 case 0xf83: //JNC Jv
2765 case 0xf84: //JZ Jv
2766 case 0xf85: //JNZ Jv
2767 case 0xf86: //JNA Jv
2768 case 0xf87: //JA Jv
2769 case 0xf88: //JS Jv
2770 case 0xf89: //JNS Jv
2771 case 0xf8a: //JP Jv
2772 case 0xf8b: //JNP Jv
2773 case 0xf8c: //JL Jv
2774 case 0xf8d: //JNL Jv
2775 case 0xf8e: //JNG Jv
2776 case 0xf8f: //JG Jv
2777 case 0xf90: //SETO
2778 case 0xf91: //SETNO
2779 case 0xf92: //SETC
2780 case 0xf93: //SETNC
2781 case 0xf94: //SETZ
2782 case 0xf95: //SETNZ
2783 case 0xf96: //SETNA
2784 case 0xf97: //SETA
2785 case 0xf98: //SETS
2786 case 0xf99: //SETNS
2787 case 0xf9a: //SETP
2788 case 0xf9b: //SETNP
2789 case 0xf9c: //SETL
2790 case 0xf9d: //SETNL
2791 case 0xf9e: //SETNG
2792 case 0xf9f: //SETG
2793 case 0xfa0: //PUSH FS
2794 case 0xfa2: //CPUID
2795 case 0xfa8: //PUSH GS
2796 case 0xfaf: //IMUL Gv, Ev
2797 case 0xfa3: //BT Ev, Gv
2798 case 0xfab: //BTS Ev, Gv
2799 case 0xfb3: //BTR Ev, Gv
2800 case 0xfbb: //BTC Ev, Gv
2801 case 0xfb2: //LSS Mp
2802 case 0xfb4: //LFS Mp
2803 case 0xfb5: //LGS Mp
2804 case 0xfb6: //MOVZX Gv, Eb
2805 case 0xfb7: //MOVZX Gv, Ew
2806 case 0xfba: //Grp 8 Ev, Ib
2807 case 0xfbc: //BSF Gv, Ev
2808 case 0xfbd: //BSR Gv, Ev
2809 case 0xfbe: //MOVSX Gv, Eb
2810 case 0xfbf: //MOVSX Gv, Ew
2811 case 0xfc8: //BSWAP EAX
2812 case 0xfc9: //BSWAP ECX
2813 case 0xfca: //BSWAP EDX
2814 case 0xfcb: //BSWAP EBX
2815 case 0xfcc: //BSWAP ESP
2816 case 0xfcd: //BSWAP EBP
2817 case 0xfce: //BSWAP ESI
2818 case 0xfcf: //BSWAP EDI
2819 case 0xd800: // FPU OPS
2820 case 0xd900: // FPU OPS
2821 case 0xda00: // FPU OPS
2822 case 0xdb00: // FPU OPS
2823 case 0xdc00: // FPU OPS
2824 case 0xdd00: // FPU OPS
2825 case 0xde00: // FPU OPS
2826 case 0xdf00: // FPU OPS
2827 return;
2831 default:
2832 throw new IllegalStateException("Missing Flags: 0x" + Integer.toHexString(opcode));
2836 private void writeInputOperands(int prefices, int opcode, int modrm, int sib, int displacement, long immediate)
2838 switch (opcode) {
2839 case 0x00: //ADD Eb, Gb
2840 case 0x08: //OR Eb, Gb
2841 case 0x10: //ADC Eb, Gb
2842 case 0x18: //SBB Eb, Gb
2843 case 0x20: //AND Eb, Gb
2844 case 0x28: //SUB Eb, Gb
2845 case 0x30: //XOR Eb, Gb
2846 case 0x38: //CMP Eb, Gb
2847 case 0x84: //TEST Eb, Gb
2848 case 0x86: //XCHG Eb, Gb
2849 load0_Eb(prefices, modrm, sib, displacement);
2850 load1_Gb(modrm);
2851 break;
2853 case 0x88: //MOV Eb, Gb
2854 load0_Gb(modrm);
2855 break;
2857 case 0x02: //ADD Gb, Eb
2858 case 0x0a: //OR Gb, Eb
2859 case 0x12: //ADC Gb, Eb
2860 case 0x1a: //SBB Gb, Eb
2861 case 0x22: //AND Gb, Eb
2862 case 0x2a: //SUB Gb, Eb
2863 case 0x32: //XOR Gb, Eb
2864 case 0x3a: //CMP Gb, Eb
2865 case 0xfc0: //XADD Eb, Gb
2866 load0_Gb(modrm);
2867 load1_Eb(prefices, modrm, sib, displacement);
2868 break;
2870 case 0x8a: //MOV Gb, Eb
2871 case 0xfb6: //MOVZX Gv, Eb
2872 case 0xfbe: //MOVSX Gv, Eb
2873 load0_Eb(prefices, modrm, sib, displacement);
2874 break;
2876 case 0x01: //ADD Ev, Gv
2877 case 0x09: //OR Ev, Gv
2878 case 0x11: //ADC Ev, Gv
2879 case 0x19: //SBB Ev, Gv
2880 case 0x21: //AND Ev, Gv
2881 case 0x29: //SUB Ev, Gv
2882 case 0x31: //XOR Ev, Gv
2883 case 0x39: //CMP Ev, Gv
2884 case 0x85: //TEST Ev, Gv
2885 case 0x87: //XCHG Ev, Gv
2886 if ((prefices & PREFICES_OPERAND) != 0) {
2887 load0_Ed(prefices, modrm, sib, displacement);
2888 load1_Gd(modrm);
2889 } else {
2890 load0_Ew(prefices, modrm, sib, displacement);
2891 load1_Gw(modrm);
2893 break;
2895 case 0x89: //MOV Ev, Gv
2896 if ((prefices & PREFICES_OPERAND) != 0) {
2897 load0_Gd(modrm);
2898 } else {
2899 load0_Gw(modrm);
2901 break;
2903 case 0x03: //ADD Gv, Ev
2904 case 0x0b: //OR Gv, Ev
2905 case 0x13: //ADC Gv, Ev
2906 case 0x1b: //SBB Gv, Ev
2907 case 0x23: //AND Gv, Ev
2908 case 0x2b: //SUB Gv, Ev
2909 case 0x33: //XOR Gv, Ev
2910 case 0x3b: //CMP Gv, Ev
2911 case 0xfaf: //IMUL Gv, Ev
2912 case 0xfbc: //BSF Gv, Ev
2913 case 0xfbd: //BSR Gv, Ev
2914 case 0xfc1: //XADD Ev, Gv
2915 if ((prefices & PREFICES_OPERAND) != 0) {
2916 load0_Gd(modrm);
2917 load1_Ed(prefices, modrm, sib, displacement);
2918 } else {
2919 load0_Gw(modrm);
2920 load1_Ew(prefices, modrm, sib, displacement);
2922 break;
2924 case 0x8b: //MOV Gv, Ev
2925 if ((prefices & PREFICES_OPERAND) != 0) {
2926 load0_Ed(prefices, modrm, sib, displacement);
2927 } else {
2928 load0_Ew(prefices, modrm, sib, displacement);
2930 break;
2932 case 0xf40: //CMOVO
2933 case 0xf41: //CMOVNO
2934 case 0xf42: //CMOVC
2935 case 0xf43: //CMOVNC
2936 case 0xf44: //CMOVZ
2937 case 0xf45: //CMOVNZ
2938 case 0xf46: //CMOVBE
2939 case 0xf47: //CMOVNBE
2940 case 0xf48: //CMOVS
2941 case 0xf49: //CMOVNS
2942 case 0xf4a: //CMOVP
2943 case 0xf4b: //CMOVNP
2944 case 0xf4c: //CMOVL
2945 case 0xf4d: //CMOVNL
2946 case 0xf4e: //CMOVLE
2947 case 0xf4f: //CMOVNLE
2948 if ((prefices & PREFICES_OPERAND) != 0) {
2949 load0_Gd(modrm);
2950 load1_Ed(prefices, modrm, sib, displacement);
2951 } else {
2952 load0_Gw(modrm);
2953 load1_Ew(prefices, modrm, sib, displacement);
2955 break;
2957 case 0x8d: //LEA Gv, M
2958 load0_M(prefices, modrm, sib, displacement);
2959 break;
2962 case 0x80: //IMM G1 Eb, Ib
2963 case 0x82: //IMM G1 Eb, Ib
2964 case 0xc0: //SFT G2 Eb, Ib
2965 load0_Eb(prefices, modrm, sib, displacement);
2966 working.write(LOAD1_IB);
2967 working.write((int)immediate);
2968 break;
2970 case 0xc6: //MOV G11 Eb, Ib
2971 case 0xb0: //MOV AL, Ib
2972 case 0xb1: //MOV CL, Ib
2973 case 0xb2: //MOV DL, Ib
2974 case 0xb3: //MOV BL, Ib
2975 case 0xb4: //MOV AH, Ib
2976 case 0xb5: //MOV CH, Ib
2977 case 0xb6: //MOV DH, Ib
2978 case 0xb7: //MOV BH, Ib
2979 case 0xe4: //IN AL, Ib
2980 case 0x70: //Jcc Jb
2981 case 0x71:
2982 case 0x72:
2983 case 0x73:
2984 case 0x74:
2985 case 0x75:
2986 case 0x76:
2987 case 0x77:
2988 case 0x78:
2989 case 0x79:
2990 case 0x7a:
2991 case 0x7b:
2992 case 0x7c:
2993 case 0x7d:
2994 case 0x7e:
2995 case 0x7f:
2996 case 0xcd: //INT Ib
2997 case 0xd4: //AAM Ib
2998 case 0xd5: //AAD Ib
2999 case 0xe0: //LOOPNZ Jb
3000 case 0xe1: //LOOPZ Jb
3001 case 0xe2: //LOOP Jb
3002 case 0xe3: //JCXZ Jb
3003 case 0xeb: //JMP Jb
3004 case 0xe5: //IN eAX, Ib
3005 working.write(LOAD0_IB);
3006 working.write((int)immediate);
3007 break;
3009 case 0x81: //IMM G1 Ev, Iv
3010 if ((prefices & PREFICES_OPERAND) != 0) {
3011 load0_Ed(prefices, modrm, sib, displacement);
3012 working.write(LOAD1_ID);
3013 working.write((int)immediate);
3014 } else {
3015 load0_Ew(prefices, modrm, sib, displacement);
3016 working.write(LOAD1_IW);
3017 working.write((int)immediate);
3019 break;
3021 case 0xc7: //MOV G11 Ev, Iv
3022 case 0x68: //PUSH Iv
3023 case 0x6a: //PUSH Ib
3024 case 0xe8: //CALL Jv
3025 case 0xe9: //JMP Jv
3026 case 0xf80: //JO Jv
3027 case 0xf81: //JNO Jv
3028 case 0xf82: //JC Jv
3029 case 0xf83: //JNC Jv
3030 case 0xf84: //JZ Jv
3031 case 0xf85: //JNZ Jv
3032 case 0xf86: //JNA Jv
3033 case 0xf87: //JA Jv
3034 case 0xf88: //JS Jv
3035 case 0xf89: //JNS Jv
3036 case 0xf8a: //JP Jv
3037 case 0xf8b: //JNP Jv
3038 case 0xf8c: //JL Jv
3039 case 0xf8d: //JNL Jv
3040 case 0xf8e: //JNG Jv
3041 case 0xf8f: //JG Jv
3042 if ((prefices & PREFICES_OPERAND) != 0) {
3043 working.write(LOAD0_ID);
3044 working.write((int)immediate);
3045 } else {
3046 working.write(LOAD0_IW);
3047 working.write((int)immediate);
3049 break;
3051 case 0xc1: //SFT G2 Ev, Ib
3052 if ((prefices & PREFICES_OPERAND) != 0) {
3053 load0_Ed(prefices, modrm, sib, displacement);
3054 working.write(LOAD1_IB);
3055 working.write((int)immediate);
3056 } else {
3057 load0_Ew(prefices, modrm, sib, displacement);
3058 working.write(LOAD1_IB);
3059 working.write((int)immediate);
3061 break;
3063 case 0x83: //IMM G1 Ev, Ib sign extend the byte to 16/32 bits
3064 if ((prefices & PREFICES_OPERAND) != 0) {
3065 load0_Ed(prefices, modrm, sib, displacement);
3066 working.write(LOAD1_ID);
3067 working.write((int)immediate);
3068 } else {
3069 load0_Ew(prefices, modrm, sib, displacement);
3070 working.write(LOAD1_IW);
3071 working.write((int)immediate);
3073 break;
3075 case 0x8f: //POP Ev
3076 case 0x58: //POP eAX
3077 case 0x59: //POP eCX
3078 case 0x5a: //POP eDX
3079 case 0x5b: //POP eBX
3080 case 0x5c: //POP eSP
3081 case 0x5d: //POP eBP
3082 case 0x5e: //POP eSI
3083 case 0x5f: //POP eDI
3084 case 0x07: //POP ES
3085 case 0x17: //POP SS
3086 case 0x1f: //POP DS
3087 break;
3089 case 0xc2: //RET Iw
3090 case 0xca: //RETF Iw
3091 working.write(LOAD0_IW);
3092 working.write((int)immediate);
3093 break;
3095 case 0x9a: //CALLF Ap
3096 case 0xea: //JMPF Ap
3097 if ((prefices & PREFICES_OPERAND) != 0) {
3098 working.write(LOAD0_ID);
3099 working.write((int)immediate);
3100 working.write(LOAD1_IW);
3101 working.write((int)(immediate >>> 32));
3102 } else {
3103 working.write(LOAD0_IW);
3104 working.write((int)(0xffff & immediate));
3105 working.write(LOAD1_IW);
3106 working.write((int)(immediate >>> 16));
3108 break;
3110 case 0x9c:
3111 switch (prefices & PREFICES_OPERAND) {
3112 case 0:
3113 working.write(LOAD0_FLAGS); break;
3114 case PREFICES_OPERAND:
3115 working.write(LOAD0_EFLAGS); break;
3117 break;
3119 case 0xec: //IN AL, DX
3120 case 0xed: //IN eAX, DX
3121 working.write(LOAD0_DX);
3122 break;
3124 case 0xee: //OUT DX, AL
3125 working.write(LOAD0_DX);
3126 working.write(LOAD1_AL);
3127 break;
3129 case 0xef: //OUT DX, eAX
3130 if ((prefices & PREFICES_OPERAND) != 0) {
3131 working.write(LOAD0_DX);
3132 working.write(LOAD1_EAX);
3133 } else {
3134 working.write(LOAD0_DX);
3135 working.write(LOAD1_AX);
3137 break;
3139 case 0x04: //ADD AL, Ib
3140 case 0x0c: //OR AL, Ib
3141 case 0x14: //ADC AL, Ib
3142 case 0x1c: //SBB AL, Ib
3143 case 0x24: //AND AL, Ib
3144 case 0x2c: //SUB AL, Ib
3145 case 0x34: //XOR AL, Ib
3146 case 0x3c: //CMP AL, Ib
3147 case 0xa8: //TEST AL, Ib
3148 working.write(LOAD0_AL);
3149 working.write(LOAD1_IB);
3150 working.write((int)immediate);
3151 break;
3153 case 0xc8: //ENTER Iw, Ib
3154 working.write(LOAD0_IW);
3155 working.write((int)(0xffffl & (immediate >>> 16)));
3156 working.write(LOAD1_IB);
3157 working.write((int)(0xffl & immediate));
3158 break;
3160 case 0x69: //IMUL Gv, Ev, Iv
3161 case 0x6b: //IMUL Gv, Ev, Ib
3162 if ((prefices & PREFICES_OPERAND) != 0) {
3163 load0_Ed(prefices, modrm, sib, displacement);
3164 working.write(LOAD1_ID);
3165 working.write((int)immediate);
3166 } else {
3167 load0_Ew(prefices, modrm, sib, displacement);
3168 working.write(LOAD1_IW);
3169 working.write((int)immediate);
3171 break;
3173 case 0xe6: //OUT Ib, AL
3174 working.write(LOAD0_IB);
3175 working.write((int)immediate);
3176 working.write(LOAD1_AL);
3177 break;
3179 case 0x05: //ADD eAX, Iv
3180 case 0x0d: //OR eAX, Iv
3181 case 0x15: //ADC eAX, Iv
3182 case 0x1d: //SBB eAX, Iv
3183 case 0x25: //AND eAX, Iv
3184 case 0x2d: //SUB eAX, Iv
3185 case 0x35: //XOR eAX, Iv
3186 case 0x3d: //CMP eAX, Iv
3187 case 0xa9: //TEST eAX, Iv
3188 if ((prefices & PREFICES_OPERAND) != 0) {
3189 working.write(LOAD0_EAX);
3190 working.write(LOAD1_ID);
3191 working.write((int)immediate);
3192 } else {
3193 working.write(LOAD0_AX);
3194 working.write(LOAD1_IW);
3195 working.write((int)immediate);
3197 break;
3199 case 0xb8: //MOV eAX, Iv
3200 case 0xb9: //MOV eCX, Iv
3201 case 0xba: //MOV eDX, Iv
3202 case 0xbb: //MOV eBX, Iv
3203 case 0xbc: //MOV eSP, Iv
3204 case 0xbd: //MOV eBP, Iv
3205 case 0xbe: //MOV eSI, Iv
3206 case 0xbf: //MOV eDI, Iv
3207 if ((prefices & PREFICES_OPERAND) != 0) {
3208 working.write(LOAD0_ID);
3209 working.write((int)immediate);
3210 } else {
3211 working.write(LOAD0_IW);
3212 working.write((int)immediate);
3214 break;
3216 case 0xe7: //OUT Ib, eAX
3217 if ((prefices & PREFICES_OPERAND) != 0) {
3218 working.write(LOAD0_IB);
3219 working.write((int)immediate);
3220 working.write(LOAD1_EAX);
3221 } else {
3222 working.write(LOAD0_IB);
3223 working.write((int)immediate);
3224 working.write(LOAD1_AX);
3226 break;
3228 case 0x40: //INC eAX
3229 case 0x48: //DEC eAX
3230 case 0x50: //PUSH eAX
3231 if ((prefices & PREFICES_OPERAND) != 0) {
3232 working.write(LOAD0_EAX);
3233 } else {
3234 working.write(LOAD0_AX);
3236 break;
3238 case 0x41: //INC eCX
3239 case 0x49: //DEC eCX
3240 case 0x51: //PUSH eCX
3241 if ((prefices & PREFICES_OPERAND) != 0) {
3242 working.write(LOAD0_ECX);
3243 } else {
3244 working.write(LOAD0_CX);
3246 break;
3248 case 0x42: //INC eDX
3249 case 0x4a: //DEC eDX
3250 case 0x52: //PUSH eDX
3251 if ((prefices & PREFICES_OPERAND) != 0) {
3252 working.write(LOAD0_EDX);
3253 } else {
3254 working.write(LOAD0_DX);
3256 break;
3258 case 0x43: //INC eBX
3259 case 0x4b: //DEC eBX
3260 case 0x53: //PUSH eBX
3261 if ((prefices & PREFICES_OPERAND) != 0) {
3262 working.write(LOAD0_EBX);
3263 } else {
3264 working.write(LOAD0_BX);
3266 break;
3268 case 0x44: //INC eSP
3269 case 0x4c: //DEC eSP
3270 case 0x54: //PUSH eSP
3271 if ((prefices & PREFICES_OPERAND) != 0) {
3272 working.write(LOAD0_ESP);
3273 } else {
3274 working.write(LOAD0_SP);
3276 break;
3278 case 0x45: //INC eBP
3279 case 0x4d: //DEC eBP
3280 case 0x55: //PUSH eBP
3281 if ((prefices & PREFICES_OPERAND) != 0) {
3282 working.write(LOAD0_EBP);
3283 } else {
3284 working.write(LOAD0_BP);
3286 break;
3288 case 0x46: //INC eSI
3289 case 0x4e: //DEC eSI
3290 case 0x56: //PUSH eSI
3291 if ((prefices & PREFICES_OPERAND) != 0) {
3292 working.write(LOAD0_ESI);
3293 } else {
3294 working.write(LOAD0_SI);
3296 break;
3298 case 0x47: //INC eDI
3299 case 0x4f: //DEC eDI
3300 case 0x57: //PUSH eDI
3301 if ((prefices & PREFICES_OPERAND) != 0) {
3302 working.write(LOAD0_EDI);
3303 } else {
3304 working.write(LOAD0_DI);
3306 break;
3308 case 0x91: //XCHG eAX, eCX
3309 if ((prefices & PREFICES_OPERAND) != 0) {
3310 working.write(LOAD0_EAX);
3311 working.write(LOAD1_ECX);
3312 } else {
3313 working.write(LOAD0_AX);
3314 working.write(LOAD1_CX);
3316 break;
3318 case 0x92: //XCHG eAX, eDX
3319 if ((prefices & PREFICES_OPERAND) != 0) {
3320 working.write(LOAD0_EAX);
3321 working.write(LOAD1_EDX);
3322 } else {
3323 working.write(LOAD0_AX);
3324 working.write(LOAD1_DX);
3326 break;
3328 case 0x93: //XCHG eAX, eBX
3329 if ((prefices & PREFICES_OPERAND) != 0) {
3330 working.write(LOAD0_EAX);
3331 working.write(LOAD1_EBX);
3332 } else {
3333 working.write(LOAD0_AX);
3334 working.write(LOAD1_BX);
3336 break;
3338 case 0x94: //XCHG eAX, eSP
3339 if ((prefices & PREFICES_OPERAND) != 0) {
3340 working.write(LOAD0_EAX);
3341 working.write(LOAD1_ESP);
3342 } else {
3343 working.write(LOAD0_AX);
3344 working.write(LOAD1_SP);
3346 break;
3348 case 0x95: //XCHG eAX, eBP
3349 if ((prefices & PREFICES_OPERAND) != 0) {
3350 working.write(LOAD0_EAX);
3351 working.write(LOAD1_EBP);
3352 } else {
3353 working.write(LOAD0_AX);
3354 working.write(LOAD1_BP);
3356 break;
3358 case 0x96: //XCHG eAX, eSI
3359 if ((prefices & PREFICES_OPERAND) != 0) {
3360 working.write(LOAD0_EAX);
3361 working.write(LOAD1_ESI);
3362 } else {
3363 working.write(LOAD0_AX);
3364 working.write(LOAD1_SI);
3366 break;
3368 case 0x97: //XCHG eAX, eDI
3369 if ((prefices & PREFICES_OPERAND) != 0) {
3370 working.write(LOAD0_EAX);
3371 working.write(LOAD1_EDI);
3372 } else {
3373 working.write(LOAD0_AX);
3374 working.write(LOAD1_DI);
3376 break;
3378 case 0xd0: //SFT G2 Eb, 1
3379 load0_Eb(prefices, modrm, sib, displacement);
3380 working.write(LOAD1_IB);
3381 working.write(1);
3382 break;
3384 case 0xd2: //SFT G2 Eb, CL
3385 load0_Eb(prefices, modrm, sib, displacement);
3386 working.write(LOAD1_CL);
3387 break;
3389 case 0xd1: //SFT G2 Ev, 1
3390 if ((prefices & PREFICES_OPERAND) != 0) {
3391 load0_Ed(prefices, modrm, sib, displacement);
3392 working.write(LOAD1_IB);
3393 working.write(1);
3394 } else {
3395 load0_Ew(prefices, modrm, sib, displacement);
3396 working.write(LOAD1_IB);
3397 working.write(1);
3399 break;
3401 case 0xd3: //SFT G2 Ev, CL
3402 if ((prefices & PREFICES_OPERAND) != 0) {
3403 load0_Ed(prefices, modrm, sib, displacement);
3404 working.write(LOAD1_CL);
3405 } else {
3406 load0_Ew(prefices, modrm, sib, displacement);
3407 working.write(LOAD1_CL);
3409 break;
3411 case 0xf6: //UNA G3 Eb, ?
3412 switch (modrm & 0x38) {
3413 case 0x00: //TEST Eb, Ib
3414 load0_Eb(prefices, modrm, sib, displacement);
3415 working.write(LOAD1_IB);
3416 working.write((int)immediate);
3417 break;
3418 case 0x10:
3419 case 0x18:
3420 load0_Eb(prefices, modrm, sib, displacement);
3421 break;
3422 case 0x20:
3423 case 0x28:
3424 load0_Eb(prefices, modrm, sib, displacement);
3425 break;
3426 case 0x30:
3427 case 0x38:
3428 load0_Eb(prefices, modrm, sib, displacement);
3429 break;
3431 break;
3433 case 0xf7: //UNA G3 Ev, ?
3434 if ((prefices & PREFICES_OPERAND) != 0) {
3435 switch (modrm & 0x38) {
3436 case 0x00: //TEST Ed, Id
3437 load0_Ed(prefices, modrm, sib, displacement);
3438 working.write(LOAD1_ID);
3439 working.write((int)immediate);
3440 break;
3441 case 0x10:
3442 case 0x18:
3443 load0_Ed(prefices, modrm, sib, displacement);
3444 break;
3445 case 0x20:
3446 case 0x28:
3447 load0_Ed(prefices, modrm, sib, displacement);
3448 break;
3449 case 0x30:
3450 case 0x38:
3451 load0_Ed(prefices, modrm, sib, displacement);
3453 } else {
3454 switch (modrm & 0x38) {
3455 case 0x00: //TEST Ew, Iw
3456 load0_Ew(prefices, modrm, sib, displacement);
3457 working.write(LOAD1_IW);
3458 working.write((int)immediate);
3459 break;
3460 case 0x10:
3461 case 0x18:
3462 load0_Ew(prefices, modrm, sib, displacement);
3463 break;
3464 case 0x20:
3465 case 0x28:
3466 load0_Ew(prefices, modrm, sib, displacement);
3467 break;
3468 case 0x30:
3469 case 0x38:
3470 load0_Ew(prefices, modrm, sib, displacement);
3473 break;
3475 case 0xfe: //INC/DEC G4 Eb
3476 load0_Eb(prefices, modrm, sib, displacement);
3477 break;
3479 case 0x06: //PUSH ES
3480 working.write(LOAD0_ES);
3481 break;
3483 case 0x0e: //PUSH CS
3484 working.write(LOAD0_CS);
3485 break;
3487 case 0x16: //PUSH SS
3488 working.write(LOAD0_SS);
3489 break;
3491 case 0x1e: //PUSH DS
3492 working.write(LOAD0_DS);
3493 break;
3495 case 0x62: //BOUND Gv, Ma
3496 if ((prefices & PREFICES_OPERAND) != 0) {
3497 load0_Eq(prefices, modrm, sib, displacement);
3498 load1_Gd(modrm);
3499 } else {
3500 load0_Ed(prefices, modrm, sib, displacement);
3501 load1_Gw(modrm);
3503 break;
3505 case 0x8c: //MOV Ew, Sw
3506 load0_Sw(modrm);
3507 break;
3509 case 0x8e: //MOV Sw, Ew
3510 case 0xfb7: //MOV Gv, Ew
3511 case 0xfbf: //MOVSX Gv, Ew
3512 load0_Ew(prefices, modrm, sib, displacement);
3513 break;
3515 case 0xa0: //MOV AL, Ob
3516 load0_Ob(prefices, displacement);
3517 break;
3519 case 0xa2: //MOV Ob, AL
3520 working.write(LOAD0_AL);
3521 break;
3523 case 0xa1: //MOV eAX, Ov
3524 if ((prefices & PREFICES_OPERAND) != 0) {
3525 load0_Od(prefices, displacement);
3526 } else {
3527 load0_Ow(prefices, displacement);
3529 break;
3531 case 0xa3: //MOV Ov, eAX
3532 if ((prefices & PREFICES_OPERAND) != 0) {
3533 working.write(LOAD0_EAX);
3534 } else {
3535 working.write(LOAD0_AX);
3537 break;
3539 case 0x6c: //INS Yb, DX (prefices do not override segment)
3540 case 0x6d: //INS Yv, DX (prefices do not override segment)
3541 working.write(LOAD0_DX);
3542 break;
3544 case 0x6e: //OUTS DX, Xb
3545 case 0x6f: //OUTS DX, Xv
3546 working.write(LOAD0_DX);
3547 decodeSegmentPrefix(prefices);
3548 break;
3550 case 0xa4: //MOVS Yb, Xb
3551 case 0xa5: //MOVS Yv, Xv
3552 case 0xa6: //CMPS Yb, Xb
3553 case 0xa7: //CMPS Xv, Yv
3554 case 0xac: //LODS AL, Xb
3555 case 0xad: //LODS eAX, Xv
3556 decodeSegmentPrefix(prefices);
3557 break;
3559 case 0xaa: //STOS Yb, AL (prefices do not override segment)
3560 working.write(LOAD0_AL);
3561 break;
3563 case 0xab: //STOS Yv, eAX
3564 if ((prefices & PREFICES_OPERAND) != 0)
3565 working.write(LOAD0_EAX);
3566 else
3567 working.write(LOAD0_AX);
3568 break;
3571 case 0xae: //SCAS AL, Yb (prefices do not override segment)
3572 working.write(LOAD0_AL);
3573 break;
3575 case 0xaf: //SCAS eAX, Yv
3576 if ((prefices & PREFICES_OPERAND) != 0)
3577 working.write(LOAD0_EAX);
3578 else
3579 working.write(LOAD0_AX);
3580 break;
3582 case 0xff: //INC/DEC G5
3583 if ((prefices & PREFICES_OPERAND) != 0) {
3584 switch (modrm & 0x38) {
3585 case 0x00: //INC Ed
3586 case 0x08: //DEC Ed
3587 case 0x10: //CALLN Ed
3588 case 0x20: //JMPN Ed
3589 case 0x30: //PUSH Ed
3590 load0_Ed(prefices, modrm, sib, displacement);
3591 break;
3592 case 0x18: //CALLF Ep
3593 case 0x28: //JMPF Ep
3594 load0_Ed(prefices, modrm, sib, displacement);
3595 working.write(ADDR_IB);
3596 working.write(4);
3597 working.write(LOAD1_MEM_WORD);
3599 } else {
3600 switch (modrm & 0x38) {
3601 case 0x00:
3602 case 0x08:
3603 case 0x10:
3604 case 0x20:
3605 case 0x30:
3606 load0_Ew(prefices, modrm, sib, displacement);
3607 break;
3608 case 0x18:
3609 case 0x28:
3610 load0_Ew(prefices, modrm, sib, displacement);
3611 working.write(ADDR_IB);
3612 working.write(2);
3613 working.write(LOAD1_MEM_WORD);
3616 break;
3618 case 0xc4: //LES Gv, Mp
3619 case 0xc5: //LDS Gv, Mp
3620 case 0xfb2: //LSS Mp
3621 case 0xfb4: //LFS Mp
3622 case 0xfb5: //LGS Mp
3623 if ((prefices & PREFICES_OPERAND) != 0) {
3624 load0_Ed(prefices, modrm, sib, displacement);
3625 working.write(ADDR_IB);
3626 working.write(4);
3627 working.write(LOAD1_MEM_WORD);
3628 } else {
3629 load0_Ew(prefices, modrm, sib, displacement);
3630 working.write(ADDR_IB);
3631 working.write(2);
3632 working.write(LOAD1_MEM_WORD);
3634 break;
3636 case 0xd7: // XLAT
3637 switch (prefices & PREFICES_SG) {
3638 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
3639 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
3640 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
3641 default:
3642 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
3643 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
3644 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
3647 if ((prefices & PREFICES_ADDRESS) != 0) {
3648 if (decodingAddressMode()) {
3649 working.write(ADDR_EBX);
3650 working.write(ADDR_uAL);
3652 } else {
3653 if (decodingAddressMode()) {
3654 working.write(ADDR_BX);
3655 working.write(ADDR_uAL);
3656 working.write(ADDR_MASK16);
3659 working.write(LOAD0_MEM_BYTE);
3660 break;
3662 case 0xf00: // Group 6
3663 switch (modrm & 0x38) {
3664 case 0x10: //LLDT
3665 case 0x18: //LTR
3666 case 0x20: //VERR
3667 case 0x28: //VERW
3668 load0_Ew(prefices, modrm, sib, displacement); break;
3669 } break;
3671 case 0xf01:
3672 switch (modrm & 0x38) {
3673 case 0x10:
3674 case 0x18:
3675 load0_Ew(prefices, modrm, sib, displacement);
3676 working.write(ADDR_ID);
3677 working.write(2);
3678 working.write(LOAD1_MEM_DWORD);
3679 break;
3680 case 0x30: load0_Ew(prefices, modrm, sib, displacement); break;
3681 case 0x38: decodeM(prefices, modrm, sib, displacement); break;
3682 } break;
3684 case 0xf09: break; //WBINVD
3686 case 0xfa0: //PUSH FS
3687 working.write(LOAD0_FS); break;
3688 case 0xfa8: //PUSH GS
3689 working.write(LOAD0_GS); break;
3691 case 0xf20: load0_Cd(modrm); break; //MOV Rd, Cd
3693 case 0xf21: load0_Dd(modrm); break; //MOV Rd, Dd
3695 case 0xf22: //MOV Cd, Rd
3696 case 0xf23: load0_Rd(modrm); break; //MOV Dd, Rd
3698 case 0xf30: //WRMSR
3699 working.write(LOAD0_ECX);
3700 working.write(LOAD1_EDX);
3701 working.write(LOAD2_EAX);
3702 break;
3704 case 0xf32: //RDMSR
3705 working.write(LOAD0_ECX);
3706 break;
3708 case 0xfa4: //SHLD Ev, Gv, Ib
3709 case 0xfac: //SHRD Ev, Gv, Ib
3710 if ((prefices & PREFICES_OPERAND) != 0) {
3711 load0_Ed(prefices, modrm, sib, displacement);
3712 load1_Gd(modrm);
3713 working.write(LOAD2_IB);
3714 working.write((int)immediate);
3715 } else {
3716 load0_Ew(prefices, modrm, sib, displacement);
3717 load1_Gw(modrm);
3718 working.write(LOAD2_IB);
3719 working.write((int)immediate);
3721 break;
3722 case 0xfa5: //SHLD Ev, Gv, CL
3723 case 0xfad: //SHRD Ev, Gv, CL
3724 if ((prefices & PREFICES_OPERAND) != 0) {
3725 load0_Ed(prefices, modrm, sib, displacement);
3726 load1_Gd(modrm);
3727 working.write(LOAD2_CL);
3728 } else {
3729 load0_Ew(prefices, modrm, sib, displacement);
3730 load1_Gw(modrm);
3731 working.write(LOAD2_CL);
3733 break;
3735 case 0xfb0: //CMPXCHG Eb, Gb
3736 load0_Eb(prefices, modrm, sib, displacement);
3737 load1_Gb(modrm);
3738 working.write(LOAD2_AL);
3739 break;
3741 case 0xfb1: //CMPXCHG Ev, Gv
3742 if ((prefices & PREFICES_OPERAND) != 0) {
3743 load0_Ed(prefices, modrm, sib, displacement);
3744 load1_Gd(modrm);
3745 working.write(LOAD2_EAX);
3746 } else {
3747 load0_Ew(prefices, modrm, sib, displacement);
3748 load1_Gw(modrm);
3749 working.write(LOAD2_AX);
3751 break;
3753 case 0xfa3: //BT Ev, Gv
3754 case 0xfab: //BTS Ev, Gv
3755 case 0xfb3: //BTR Ev, Gv
3756 case 0xfbb: //BTC Ev, Gv
3757 if ((prefices & PREFICES_OPERAND) != 0) {
3758 switch (modrm & 0xc7) {
3759 default: decodeM(prefices, modrm, sib, displacement); break;
3761 case 0xc0: working.write(LOAD0_EAX); break;
3762 case 0xc1: working.write(LOAD0_ECX); break;
3763 case 0xc2: working.write(LOAD0_EDX); break;
3764 case 0xc3: working.write(LOAD0_EBX); break;
3765 case 0xc4: working.write(LOAD0_ESP); break;
3766 case 0xc5: working.write(LOAD0_EBP); break;
3767 case 0xc6: working.write(LOAD0_ESI); break;
3768 case 0xc7: working.write(LOAD0_EDI); break;
3770 load1_Gd(modrm);
3771 } else {
3772 switch (modrm & 0xc7) {
3773 default: decodeM(prefices, modrm, sib, displacement); break;
3775 case 0xc0: working.write(LOAD0_AX); break;
3776 case 0xc1: working.write(LOAD0_CX); break;
3777 case 0xc2: working.write(LOAD0_DX); break;
3778 case 0xc3: working.write(LOAD0_BX); break;
3779 case 0xc4: working.write(LOAD0_SP); break;
3780 case 0xc5: working.write(LOAD0_BP); break;
3781 case 0xc6: working.write(LOAD0_SI); break;
3782 case 0xc7: working.write(LOAD0_DI); break;
3784 load1_Gw(modrm);
3786 break;
3788 case 0xfba: //Grp 8 Ev, Ib
3789 if ((prefices & PREFICES_OPERAND) != 0) {
3790 switch (modrm & 0xc7) {
3791 default: decodeM(prefices, modrm, sib, displacement); break;
3793 case 0xc0: working.write(LOAD0_EAX); break;
3794 case 0xc1: working.write(LOAD0_ECX); break;
3795 case 0xc2: working.write(LOAD0_EDX); break;
3796 case 0xc3: working.write(LOAD0_EBX); break;
3797 case 0xc4: working.write(LOAD0_ESP); break;
3798 case 0xc5: working.write(LOAD0_EBP); break;
3799 case 0xc6: working.write(LOAD0_ESI); break;
3800 case 0xc7: working.write(LOAD0_EDI); break;
3802 } else {
3803 switch (modrm & 0xc7) {
3804 default: decodeM(prefices, modrm, sib, displacement); break;
3806 case 0xc0: working.write(LOAD0_AX); break;
3807 case 0xc1: working.write(LOAD0_CX); break;
3808 case 0xc2: working.write(LOAD0_DX); break;
3809 case 0xc3: working.write(LOAD0_BX); break;
3810 case 0xc4: working.write(LOAD0_SP); break;
3811 case 0xc5: working.write(LOAD0_BP); break;
3812 case 0xc6: working.write(LOAD0_SI); break;
3813 case 0xc7: working.write(LOAD0_DI); break;
3816 working.write(LOAD1_IB);
3817 working.write((int)immediate & 0x1f);
3818 break;
3820 case 0xfc8: working.write(LOAD0_EAX); break; //BSWAP EAX
3821 case 0xfc9: working.write(LOAD0_ECX); break; //BSWAP ECX
3822 case 0xfca: working.write(LOAD0_EDX); break; //BSWAP EDX
3823 case 0xfcb: working.write(LOAD0_EBX); break; //BSWAP EBX
3824 case 0xfcc: working.write(LOAD0_ESP); break; //BSWAP ESP
3825 case 0xfcd: working.write(LOAD0_EBP); break; //BSWAP EBP
3826 case 0xfce: working.write(LOAD0_ESI); break; //BSWAP ESI
3827 case 0xfcf: working.write(LOAD0_EDI); break; //BSWAP EDI
3829 case 0xd800:
3830 working.write(FWAIT);
3831 if ((modrm & 0xc0) != 0xc0)
3833 switch (modrm & 0x38)
3835 case 0x28:
3836 case 0x38:
3837 decodeM(prefices, modrm, sib, displacement);
3838 working.write(FLOAD0_MEM_SINGLE);
3839 working.write(FLOAD1_ST0);
3840 break;
3841 default:
3842 working.write(FLOAD0_ST0);
3843 decodeM(prefices, modrm, sib, displacement);
3844 working.write(FLOAD1_MEM_SINGLE);
3845 break;
3848 else
3850 switch (modrm & 0xf8)
3852 case 0xe8:
3853 case 0xf8:
3854 working.write(FLOAD0_STN);
3855 working.write(modrm & 0x07);
3856 working.write(FLOAD1_ST0);
3857 break;
3858 default:
3859 working.write(FLOAD0_ST0);
3860 working.write(FLOAD1_STN);
3861 working.write(modrm & 0x07);
3862 break;
3865 break;
3867 case 0xd900:
3868 if ((modrm & 0xc0) != 0xc0)
3870 switch (modrm & 0x38)
3872 case 0x00:
3873 working.write(FWAIT);
3874 decodeM(prefices, modrm, sib, displacement);
3875 working.write(FLOAD0_MEM_SINGLE);
3876 break;
3877 case 0x10:
3878 case 0x18:
3879 working.write(FWAIT);
3880 working.write(FLOAD0_ST0); break;
3881 case 0x20:
3882 working.write(FWAIT);
3883 decodeM(prefices, modrm, sib, displacement);
3884 break;
3885 case 0x28:
3886 working.write(FWAIT);
3887 decodeM(prefices, modrm, sib, displacement);
3888 working.write(LOAD0_MEM_WORD);
3889 break;
3890 case 0x30: decodeM(prefices, modrm, sib, displacement); break;
3891 case 0x38: working.write(LOAD0_FPUCW); break;
3894 else
3896 working.write(FWAIT);
3897 switch (modrm & 0xf8)
3899 case 0xc0:
3900 working.write(FLOAD0_STN);
3901 working.write(modrm & 0x07);
3902 break;
3903 case 0xc8:
3904 working.write(FLOAD0_ST0);
3905 working.write(FLOAD1_STN);
3906 working.write(modrm & 0x07);
3907 break;
3909 switch (modrm)
3911 case 0xd0:
3912 case 0xf6:
3913 case 0xf7: break;
3914 case 0xe0:
3915 case 0xe1:
3916 case 0xe5:
3917 case 0xf0:
3918 case 0xf2:
3919 case 0xf4:
3920 case 0xfa:
3921 case 0xfb:
3922 case 0xfc:
3923 case 0xfe:
3924 case 0xff: working.write(FLOAD0_ST0); break;
3925 case 0xf1:
3926 case 0xf3:
3927 case 0xf5:
3928 case 0xf8:
3929 case 0xf9:
3930 case 0xfd:
3931 working.write(FLOAD0_ST0);
3932 working.write(FLOAD1_STN);
3933 working.write(1);
3934 break;
3935 case 0xe4:
3936 working.write(FLOAD0_ST0);
3937 working.write(FLOAD1_POS0);
3938 break;
3939 case 0xe8: working.write(FLOAD0_1); break;
3940 case 0xe9: working.write(FLOAD0_L2TEN); break;
3941 case 0xea: working.write(FLOAD0_L2E); break;
3942 case 0xeb: working.write(FLOAD0_PI); break;
3943 case 0xec: working.write(FLOAD0_LOG2); break;
3944 case 0xed: working.write(FLOAD0_LN2); break;
3945 case 0xee: working.write(FLOAD0_POS0); break;
3948 break;
3950 case 0xda00:
3951 working.write(FWAIT);
3952 if ((modrm & 0xc0) != 0xc0)
3954 switch (modrm & 0x38)
3956 case 0x28:
3957 case 0x38:
3958 decodeM(prefices, modrm, sib, displacement);
3959 working.write(LOAD0_MEM_DWORD);
3960 working.write(FLOAD0_REG0);
3961 working.write(FLOAD1_ST0);
3962 break;
3963 default:
3964 working.write(FLOAD0_ST0);
3965 decodeM(prefices, modrm, sib, displacement);
3966 working.write(LOAD0_MEM_DWORD);
3967 working.write(FLOAD1_REG0);
3968 break;
3971 else
3973 switch (modrm & 0xf8)
3975 case 0xc0:
3976 case 0xc8:
3977 case 0xd0:
3978 case 0xd8:
3979 working.write(FLOAD0_STN);
3980 working.write(modrm & 0x07);
3981 break;
3983 switch (modrm)
3985 case 0xe9:
3986 working.write(FLOAD0_ST0);
3987 working.write(FLOAD1_STN);
3988 working.write(1);
3989 break;
3992 break;
3994 case 0xdb00:
3995 if ((modrm & 0xc0) != 0xc0)
3997 working.write(FWAIT);
3998 switch (modrm & 0x38)
4000 case 0x00:
4001 decodeM(prefices, modrm, sib, displacement);
4002 working.write(LOAD0_MEM_DWORD);
4003 working.write(FLOAD0_REG0);
4004 break;
4005 case 0x08:
4006 case 0x10:
4007 case 0x18:
4008 case 0x38: working.write(FLOAD0_ST0); break;
4009 case 0x28:
4010 decodeM(prefices, modrm, sib, displacement);
4011 working.write(FLOAD0_MEM_EXTENDED);
4012 break;
4015 else
4017 switch (modrm)
4019 case 0xe2:
4020 case 0xe3: break;
4021 default: working.write(FWAIT); break;
4023 switch (modrm & 0xf8)
4025 case 0xc0:
4026 case 0xc8:
4027 case 0xd0:
4028 case 0xd8:
4029 working.write(FLOAD0_STN);
4030 working.write(modrm & 0x07);
4031 break;
4032 case 0xe8:
4033 case 0xf0:
4034 working.write(FLOAD0_ST0);
4035 working.write(FLOAD1_STN);
4036 working.write(modrm & 0x07);
4037 break;
4040 break;
4042 case 0xdc00:
4043 working.write(FWAIT);
4044 if ((modrm & 0xc0) != 0xc0)
4046 switch (modrm & 0x38)
4048 case 0x28:
4049 case 0x38:
4050 decodeM(prefices, modrm, sib, displacement);
4051 working.write(FLOAD0_MEM_DOUBLE);
4052 working.write(FLOAD1_ST0);
4053 break;
4054 default:
4055 working.write(FLOAD0_ST0);
4056 decodeM(prefices, modrm, sib, displacement);
4057 working.write(FLOAD1_MEM_DOUBLE);
4058 break;
4061 else
4063 switch (modrm & 0xf8)
4065 case 0xe8:
4066 case 0xf8:
4067 working.write(FLOAD0_STN);
4068 working.write(modrm & 0x07);
4069 working.write(FLOAD1_ST0);
4070 break;
4071 default:
4072 working.write(FLOAD0_ST0);
4073 working.write(FLOAD1_STN);
4074 working.write(modrm & 0x07);
4075 break;
4078 break;
4080 case 0xdd00:
4081 if ((modrm & 0xc0) != 0xc0)
4083 switch (modrm & 0x38)
4085 case 0x00:
4086 working.write(FWAIT);
4087 decodeM(prefices, modrm, sib, displacement);
4088 working.write(FLOAD0_MEM_DOUBLE);
4089 break;
4090 case 0x08:
4091 case 0x10:
4092 case 0x18:
4093 working.write(FWAIT);
4094 working.write(FLOAD0_ST0);
4095 break;
4096 case 0x20:
4097 working.write(FWAIT);
4098 decodeM(prefices, modrm, sib, displacement);
4099 break;
4100 case 0x30: decodeM(prefices, modrm, sib, displacement); break;
4101 case 0x38: working.write(LOAD0_FPUSW); break;
4104 else
4106 working.write(FWAIT);
4107 switch (modrm & 0xf8)
4109 case 0xc0:
4110 working.write(LOAD0_ID);
4111 working.write(modrm & 0x07);
4112 break;
4113 case 0xd0:
4114 case 0xd8: working.write(FLOAD0_ST0); break;
4115 case 0xe0:
4116 case 0xe8:
4117 working.write(FLOAD0_ST0);
4118 working.write(FLOAD1_STN);
4119 working.write(modrm & 0x07);
4120 break;
4123 break;
4125 case 0xde00:
4126 working.write(FWAIT);
4127 if ((modrm & 0xc0) != 0xc0)
4129 switch (modrm & 0x38)
4131 case 0x28:
4132 case 0x38:
4133 decodeM(prefices, modrm, sib, displacement);
4134 working.write(LOAD0_MEM_WORD);
4135 working.write(FLOAD0_REG0);
4136 working.write(FLOAD1_ST0);
4137 break;
4138 case 0x30:
4139 working.write(FLOAD0_ST0);
4140 decodeM(prefices, modrm, sib, displacement);
4141 working.write(LOAD0_MEM_QWORD);
4142 working.write(FLOAD1_REG0L);
4143 break;
4144 default:
4145 working.write(FLOAD0_ST0);
4146 decodeM(prefices, modrm, sib, displacement);
4147 working.write(LOAD0_MEM_WORD);
4148 working.write(FLOAD1_REG0);
4149 break;
4152 else
4154 switch (modrm & 0xf8) {
4155 case 0xc0:
4156 case 0xc8:
4157 case 0xe0:
4158 case 0xf0:
4159 working.write(FLOAD0_ST0);
4160 working.write(FLOAD1_STN);
4161 working.write(modrm & 0x07);
4162 break;
4163 case 0xe8:
4164 case 0xf8:
4165 working.write(FLOAD1_ST0);
4166 working.write(FLOAD0_STN);
4167 working.write(modrm & 0x07);
4168 break;
4170 switch (modrm)
4172 case 0xd9:
4173 working.write(FLOAD0_ST0);
4174 working.write(FLOAD1_STN);
4175 working.write(1);
4176 break;
4179 break;
4181 case 0xdf00:
4182 if ((modrm & 0xc0) != 0xc0)
4184 working.write(FWAIT);
4185 switch (modrm & 0x38)
4187 case 0x00:
4188 decodeM(prefices, modrm, sib, displacement);
4189 working.write(LOAD0_MEM_WORD);
4190 working.write(FLOAD0_REG0);
4191 break;
4192 case 0x28:
4193 decodeM(prefices, modrm, sib, displacement);
4194 working.write(LOAD0_MEM_QWORD);
4195 working.write(FLOAD0_REG0L);
4196 break;
4197 case 0x08:
4198 case 0x10:
4199 case 0x18:
4200 case 0x38:
4201 working.write(FLOAD0_ST0);
4202 break;
4203 case 0x30:
4204 working.write(FLOAD0_ST0);
4205 decodeM(prefices, modrm, sib, displacement);
4206 break;
4207 case 0x20:
4208 decodeM(prefices, modrm, sib, displacement);
4209 break;
4212 else
4214 switch (modrm)
4216 case 0xe0: working.write(LOAD0_FPUSW); break;
4217 default: working.write(FWAIT); break;
4219 switch (modrm & 0xf8) {
4220 case 0xe8:
4221 case 0xf0:
4222 working.write(FLOAD0_ST0);
4223 working.write(FLOAD1_STN);
4224 working.write(modrm & 0x07);
4225 break;
4228 break;
4233 private void writeOutputOperands(int prefices, int opcode, int modrm, int sib, int displacement)
4235 //Normal One Byte Operation
4236 switch (opcode) {
4237 case 0x00: //ADD Eb, Gb
4238 case 0x08: //OR Eb, Gb
4239 case 0x10: //ADC Eb, Gb
4240 case 0x18: //SBB Eb, Gb
4241 case 0x20: //AND Eb, Gb
4242 case 0x28: //SUB Eb, Gb
4243 case 0x30: //XOR Eb, Gb
4244 case 0x88: //MOV Eb, Gb
4245 case 0xc0: //SFT G2 Eb, Ib
4246 case 0xc6: //MOV G11 Eb, Ib
4247 case 0xfe: //INC/DEC G4 Eb
4248 case 0xf90: //SETO
4249 case 0xf91: //SETNO
4250 case 0xf92: //SETC
4251 case 0xf93: //SETNC
4252 case 0xf94: //SETZ
4253 case 0xf95: //SETNZ
4254 case 0xf96: //SETBE
4255 case 0xf97: //SETNBE
4256 case 0xf98: //SETS
4257 case 0xf99: //SETNS
4258 case 0xf9a: //SETP
4259 case 0xf9b: //SETNP
4260 case 0xf9c: //SETL
4261 case 0xf9d: //SETNL
4262 case 0xf9e: //SETLE
4263 case 0xf9f: //SETNLE
4264 store0_Eb(prefices, modrm, sib, displacement);
4265 break;
4267 case 0xfb0: //CMPXCHG Eb, Gb
4268 working.write(STORE1_AL); //do store 1 first incase Eb is also AL/AX/EAX
4269 store0_Eb(prefices, modrm, sib, displacement);
4270 break;
4272 case 0x80: //IMM G1 Eb, Ib
4273 case 0x82: //IMM G1 Eb, Ib
4274 if ((modrm & 0x38) == 0x38)
4275 break;
4276 store0_Eb(prefices, modrm, sib, displacement); break;
4278 case 0x86: //XCHG Eb, Gb
4279 store0_Gb(modrm);
4280 store1_Eb(prefices, modrm, sib, displacement);
4281 break;
4283 case 0x02: //ADD Gb, Eb
4284 case 0x0a: //OR Gb, Eb
4285 case 0x12: //ADC Gb, Eb
4286 case 0x1a: //SBB Gb, Eb
4287 case 0x22: //AND Gb, Eb
4288 case 0x2a: //SUB Gb, Eb
4289 case 0x32: //XOR Gb, Eb
4290 case 0x8a: //MOV Gb, Eb
4291 store0_Gb(modrm);
4292 break;
4294 case 0x01: //ADD Ev, Gv
4295 case 0x09: //OR Ev, Gv
4296 case 0x11: //ADC Ev, Gv
4297 case 0x19: //SBB Ev, Gv
4298 case 0x21: //AND Ev, Gv
4299 case 0x29: //SUB Ev, Gv
4300 case 0x31: //XOR Ev, Gv
4301 case 0x89: //MOV Ev, Gv
4302 case 0xc7: //MOV G11 Ev, Iv
4303 case 0xc1: //SFT G2 Ev, Ib
4304 case 0x8f: //POP Ev
4305 case 0xd1: //SFT G2 Ev, 1
4306 case 0xd3: //SFT G2 Ev, CL
4307 if ((prefices & PREFICES_OPERAND) != 0) {
4308 store0_Ed(prefices, modrm, sib, displacement);
4309 } else {
4310 store0_Ew(prefices, modrm, sib, displacement);
4312 break;
4314 case 0xfb1: //CMPXCHG Ev, Gv
4315 if ((prefices & PREFICES_OPERAND) != 0) {
4316 working.write(STORE1_EAX); //do store1 first incase Eb is same place
4317 store0_Ed(prefices, modrm, sib, displacement);
4318 } else {
4319 working.write(STORE1_AX); //do store1 first incase Eb is same place
4320 store0_Ew(prefices, modrm, sib, displacement);
4322 break;
4324 case 0x81: //IMM G1 Ev, Iv
4325 case 0x83: //IMM G1 Ev, Ib
4326 if ((modrm & 0x38) == 0x38)
4327 break;
4328 if ((prefices & PREFICES_OPERAND) != 0) {
4329 store0_Ed(prefices, modrm, sib, displacement);
4330 } else {
4331 store0_Ew(prefices, modrm, sib, displacement);
4333 break;
4336 case 0x87: //XCHG Ev, Gv
4337 if ((prefices & PREFICES_OPERAND) != 0) {
4338 store0_Gd(modrm);
4339 store1_Ed(prefices, modrm, sib, displacement);
4340 } else {
4341 store0_Gw(modrm);
4342 store1_Ew(prefices, modrm, sib, displacement);
4344 break;
4346 case 0x03: //ADD Gv, Ev
4347 case 0x0b: //OR Gv, Ev
4348 case 0x13: //ADC Gv, Ev
4349 case 0x1b: //SBB Gv, Ev
4350 case 0x23: //AND Gv, Ev
4351 case 0x2b: //SUB Gv, Ev
4352 case 0x33: //XOR Gv, Ev
4353 case 0x69: //IMUL Gv, Ev, Iv
4354 case 0x6b: //IMUL Gv, Ev, Ib
4355 case 0x8b: //MOV Gv, Ev
4356 case 0x8d: //LEA Gv, M
4357 case 0xf40: //CMOVO
4358 case 0xf41: //CMOVNO
4359 case 0xf42: //CMOVC
4360 case 0xf43: //CMOVNC
4361 case 0xf44: //CMOVZ
4362 case 0xf45: //CMOVNZ
4363 case 0xf46: //CMOVBE
4364 case 0xf47: //CMOVNBE
4365 case 0xf48: //CMOVS
4366 case 0xf49: //CMOVNS
4367 case 0xf4a: //CMOVP
4368 case 0xf4b: //CMOVNP
4369 case 0xf4c: //CMOVL
4370 case 0xf4d: //CMOVNL
4371 case 0xf4e: //CMOVLE
4372 case 0xf4f: //CMOVNLE
4373 case 0xfaf: //IMUL Gv, Ev
4374 case 0xfb6: //MOVZX Gv, Eb
4375 case 0xfb7: //MOVZX Gv, Ew
4376 case 0xfbc: //BSF Gv, Ev
4377 case 0xfbd: //BSR Gv, Ev
4378 case 0xfbe: //MOVSX Gv, Eb
4379 case 0xfbf: //MOVSX Gv, Ew
4380 if ((prefices & PREFICES_OPERAND) != 0) {
4381 store0_Gd(modrm);
4382 } else {
4383 store0_Gw(modrm);
4385 break;
4387 case 0xec: //IN AL, DX
4388 case 0x04: //ADD AL, Ib
4389 case 0x0c: //OR AL, Ib
4390 case 0x14: //ADC AL, Ib
4391 case 0x1c: //SBB AL, Ib
4392 case 0x24: //AND AL, Ib
4393 case 0x2c: //SUB AL, Ib
4394 case 0x34: //XOR AL, Ib
4395 case 0xe4: //IN AL, Ib
4396 case 0xb0: //MOV AL, Ib
4397 working.write(STORE0_AL);
4398 break;
4400 case 0xb1: //MOV CL, Ib
4401 working.write(STORE0_CL);
4402 break;
4404 case 0xb2: //MOV DL, Ib
4405 working.write(STORE0_DL);
4406 break;
4408 case 0xb3: //MOV BL, Ib
4409 working.write(STORE0_BL);
4410 break;
4412 case 0xb4: //MOV AH, Ib
4413 working.write(STORE0_AH);
4414 break;
4416 case 0xb5: //MOV CH, Ib
4417 working.write(STORE0_CH);
4418 break;
4420 case 0xb6: //MOV DH, Ib
4421 working.write(STORE0_DH);
4422 break;
4424 case 0xb7: //MOV BH, Ib
4425 working.write(STORE0_BH);
4426 break;
4430 case 0x05: //ADD eAX, Iv
4431 case 0x0d: //OR eAX, Iv
4432 case 0x15: //ADC eAX, Iv
4433 case 0x1d: //SBB eAX, Iv
4434 case 0x25: //AND eAX, Iv
4435 case 0x2d: //SUB eAX, Iv
4436 case 0x35: //XOR eAX, Iv
4437 case 0xb8: //MOV eAX, Iv
4438 case 0xe5: //IN eAX, Ib
4439 case 0x40: //INC eAX
4440 case 0x48: //DEC eAX
4441 case 0x58: //POP eAX
4442 case 0xed: //IN eAX, DX
4443 if ((prefices & PREFICES_OPERAND) != 0) {
4444 working.write(STORE0_EAX);
4445 } else {
4446 working.write(STORE0_AX);
4448 break;
4450 case 0x41: //INC eCX
4451 case 0x49: //DEC eCX
4452 case 0x59: //POP eCX
4453 case 0xb9: //MOV eCX, Iv
4454 if ((prefices & PREFICES_OPERAND) != 0) {
4455 working.write(STORE0_ECX);
4456 } else {
4457 working.write(STORE0_CX);
4459 break;
4461 case 0x42: //INC eDX
4462 case 0x4a: //DEC eDX
4463 case 0x5a: //POP eDX
4464 case 0xba: //MOV eDX, Iv
4465 if ((prefices & PREFICES_OPERAND) != 0) {
4466 working.write(STORE0_EDX);
4467 } else {
4468 working.write(STORE0_DX);
4470 break;
4472 case 0x43: //INC eBX
4473 case 0x4b: //DEC eBX
4474 case 0x5b: //POP eBX
4475 case 0xbb: //MOV eBX, Iv
4476 if ((prefices & PREFICES_OPERAND) != 0) {
4477 working.write(STORE0_EBX);
4478 } else {
4479 working.write(STORE0_BX);
4481 break;
4483 case 0x44: //INC eSP
4484 case 0x4c: //DEC eSP
4485 case 0x5c: //POP eSP
4486 case 0xbc: //MOV eSP, Iv
4487 if ((prefices & PREFICES_OPERAND) != 0) {
4488 working.write(STORE0_ESP);
4489 } else {
4490 working.write(STORE0_SP);
4492 break;
4494 case 0x45: //INC eBP
4495 case 0x4d: //DEC eBP
4496 case 0x5d: //POP eBP
4497 case 0xbd: //MOV eBP, Iv
4498 if ((prefices & PREFICES_OPERAND) != 0) {
4499 working.write(STORE0_EBP);
4500 } else {
4501 working.write(STORE0_BP);
4503 break;
4505 case 0x46: //INC eSI
4506 case 0x4e: //DEC eSI
4507 case 0x5e: //POP eSI
4508 case 0xbe: //MOV eSI, Iv
4509 if ((prefices & PREFICES_OPERAND) != 0) {
4510 working.write(STORE0_ESI);
4511 } else {
4512 working.write(STORE0_SI);
4514 break;
4516 case 0x47: //INC eDI
4517 case 0x4f: //DEC eDI
4518 case 0x5f: //POP eDI
4519 case 0xbf: //MOV eDI, Iv
4520 if ((prefices & PREFICES_OPERAND) != 0) {
4521 working.write(STORE0_EDI);
4522 } else {
4523 working.write(STORE0_DI);
4525 break;
4528 case 0x91: //XCHG eAX, eCX
4529 if ((prefices & PREFICES_OPERAND) != 0) {
4530 working.write(STORE0_ECX);
4531 working.write(STORE1_EAX);
4532 } else {
4533 working.write(STORE0_CX);
4534 working.write(STORE1_AX);
4536 break;
4538 case 0x92: //XCHG eAX, eDX
4539 if ((prefices & PREFICES_OPERAND) != 0) {
4540 working.write(STORE0_EDX);
4541 working.write(STORE1_EAX);
4542 } else {
4543 working.write(STORE0_DX);
4544 working.write(STORE1_AX);
4546 break;
4548 case 0x93: //XCHG eAX, eBX
4549 if ((prefices & PREFICES_OPERAND) != 0) {
4550 working.write(STORE0_EBX);
4551 working.write(STORE1_EAX);
4552 } else {
4553 working.write(STORE0_BX);
4554 working.write(STORE1_AX);
4556 break;
4558 case 0x94: //XCHG eAX, eSP
4559 if ((prefices & PREFICES_OPERAND) != 0) {
4560 working.write(STORE0_ESP);
4561 working.write(STORE1_EAX);
4562 } else {
4563 working.write(STORE0_SP);
4564 working.write(STORE1_AX);
4566 break;
4568 case 0x95: //XCHG eAX, eBP
4569 if ((prefices & PREFICES_OPERAND) != 0) {
4570 working.write(STORE0_EBP);
4571 working.write(STORE1_EAX);
4572 } else {
4573 working.write(STORE0_BP);
4574 working.write(STORE1_AX);
4576 break;
4578 case 0x96: //XCHG eAX, eSI
4579 if ((prefices & PREFICES_OPERAND) != 0) {
4580 working.write(STORE0_ESI);
4581 working.write(STORE1_EAX);
4582 } else {
4583 working.write(STORE0_SI);
4584 working.write(STORE1_AX);
4586 break;
4588 case 0x97: //XCHG eAX, eDI
4589 if ((prefices & PREFICES_OPERAND) != 0) {
4590 working.write(STORE0_EDI);
4591 working.write(STORE1_EAX);
4592 } else {
4593 working.write(STORE0_DI);
4594 working.write(STORE1_AX);
4596 break;
4598 case 0x9d: //POPF
4599 switch (prefices & PREFICES_OPERAND) {
4600 case 0:
4601 working.write(STORE0_FLAGS); break;
4602 case PREFICES_OPERAND:
4603 working.write(STORE0_EFLAGS); break;
4605 break;
4607 case 0xd0: //SFT G2 Eb, 1
4608 case 0xd2: //SFT G2 Eb, CL
4609 store0_Eb(prefices, modrm, sib, displacement);
4610 break;
4614 case 0xf6: //UNA G3 Eb, ?
4615 switch (modrm & 0x38) {
4616 case 0x10:
4617 case 0x18:
4618 store0_Eb(prefices, modrm, sib, displacement);
4619 break;
4621 break;
4623 case 0xf7: //UNA G3 Ev, ?
4624 if ((prefices & PREFICES_OPERAND) != 0) {
4625 switch (modrm & 0x38) {
4626 case 0x10:
4627 case 0x18:
4628 store0_Ed(prefices, modrm, sib, displacement);
4629 break;
4631 } else {
4632 switch (modrm & 0x38) {
4633 case 0x10:
4634 case 0x18:
4635 store0_Ew(prefices, modrm, sib, displacement);
4636 break;
4639 break;
4642 case 0x07: //POP ES
4643 working.write(STORE0_ES);
4644 break;
4646 case 0x17: //POP SS
4647 working.write(STORE0_SS);
4648 break;
4650 case 0x1f: //POP DS
4651 working.write(STORE0_DS);
4652 break;
4654 case 0x8c: //MOV Ew, Sw
4655 if ((prefices & PREFICES_OPERAND) != 0) {
4656 store0_Ed(prefices, modrm, sib, displacement);
4657 } else {
4658 store0_Ew(prefices, modrm, sib, displacement);
4660 break;
4662 case 0x8e: //MOV Sw, Ew
4663 store0_Sw(modrm);
4664 break;
4666 case 0xa0: //MOV AL, Ob
4667 working.write(STORE0_AL);
4668 break;
4670 case 0xa2: //MOV Ob, AL
4671 store0_Ob(prefices, displacement);
4672 break;
4674 case 0xa1: //MOV eAX, Ov
4675 if ((prefices & PREFICES_OPERAND) != 0) {
4676 working.write(STORE0_EAX);
4677 } else {
4678 working.write(STORE0_AX);
4680 break;
4682 case 0xa3: //MOV Ov, eAX
4683 if ((prefices & PREFICES_OPERAND) != 0) {
4684 store0_Od(prefices, displacement);
4685 } else {
4686 store0_Ow(prefices, displacement);
4688 break;
4690 case 0xff: //INC/DEC G5
4691 if ((prefices & PREFICES_OPERAND) != 0) {
4692 switch (modrm & 0x38) {
4693 case 0x00: //INC Ed
4694 case 0x08: //DEC Ed
4695 store0_Ed(prefices, modrm, sib, displacement);
4697 } else {
4698 switch (modrm & 0x38) {
4699 case 0x00:
4700 case 0x08:
4701 store0_Ew(prefices, modrm, sib, displacement);
4704 break;
4706 case 0xc4: //LES Gv, Mp
4707 if ((prefices & PREFICES_OPERAND) != 0) {
4708 store0_Gd(modrm);
4709 working.write(STORE1_ES);
4710 } else {
4711 store0_Gw(modrm);
4712 working.write(STORE1_ES);
4714 break;
4716 case 0xc5: //LDS Gv, Mp
4717 if ((prefices & PREFICES_OPERAND) != 0) {
4718 store0_Gd(modrm);
4719 working.write(STORE1_DS);
4720 } else {
4721 store0_Gw(modrm);
4722 working.write(STORE1_DS);
4724 break;
4726 case 0xf00: // Group 6
4727 switch (modrm & 0x38) {
4728 case 0x00: //SLDT
4729 store0_Ew(prefices, modrm, sib, displacement); break;
4730 case 0x08: //STR (stores to a doubleword if a register, but a word if memory)
4731 if ((prefices & PREFICES_OPERAND) != 0) {
4732 switch (modrm & 0xc7) {
4733 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_WORD); break;
4735 case 0xc0: working.write(STORE0_EAX); break;
4736 case 0xc1: working.write(STORE0_ECX); break;
4737 case 0xc2: working.write(STORE0_EDX); break;
4738 case 0xc3: working.write(STORE0_EBX); break;
4739 case 0xc4: working.write(STORE0_ESP); break;
4740 case 0xc5: working.write(STORE0_EBP); break;
4741 case 0xc6: working.write(STORE0_ESI); break;
4742 case 0xc7: working.write(STORE0_EDI); break;
4745 else
4746 store0_Ew(prefices, modrm, sib, displacement);
4747 break;
4748 } break;
4750 case 0xf01:
4751 switch (modrm & 0x38) {
4752 case 0x00:
4753 case 0x08:
4754 store0_Ew(prefices, modrm, sib, displacement);
4755 working.write(ADDR_ID);
4756 working.write(2);
4757 working.write(STORE1_MEM_DWORD);
4758 break;
4759 case 0x20: store0_Ew(prefices, modrm, sib, displacement); break;
4760 } break;
4762 case 0xfa4: //SHLD Ev, Gv, Ib
4763 case 0xfa5: //SHLD Ev, Gv, CL
4764 case 0xfac: //SHRD Ev, Gv, Ib
4765 case 0xfad: //SHRD Ev, Gv, CL
4766 if ((prefices & PREFICES_OPERAND) != 0)
4767 store0_Ed(prefices, modrm, sib, displacement);
4768 else
4769 store0_Ew(prefices, modrm, sib, displacement);
4770 break;
4772 case 0xfb2: //LSS Mp
4773 if ((prefices & PREFICES_OPERAND) != 0) {
4774 store0_Gd(modrm);
4775 working.write(STORE1_SS);
4776 } else {
4777 store0_Gw(modrm);
4778 working.write(STORE1_SS);
4780 break;
4782 case 0xfb4: //LFS Mp
4783 if ((prefices & PREFICES_OPERAND) != 0) {
4784 store0_Gd(modrm);
4785 working.write(STORE1_FS);
4786 } else {
4787 store0_Gw(modrm);
4788 working.write(STORE1_FS);
4790 break;
4792 case 0xfb5: //LGS Mp
4793 if ((prefices & PREFICES_OPERAND) != 0) {
4794 store0_Gd(modrm);
4795 working.write(STORE1_GS);
4796 } else {
4797 store0_Gw(modrm);
4798 working.write(STORE1_GS);
4800 break;
4802 case 0xfc0: //XADD Eb, Gb
4803 store1_Gb(modrm); //exchange first then add (so we write the result of the exchange first incase Eb and Gb are same reg)
4804 store0_Eb(prefices, modrm, sib, displacement);
4805 break;
4807 case 0xfc1: //XADD Eb, Gb
4808 if ((prefices & PREFICES_OPERAND) != 0) {
4809 store1_Gd(modrm); //exchange first then add
4810 store0_Ed(prefices, modrm, sib, displacement);
4811 } else {
4812 store1_Gw(modrm); //exchange first then add
4813 store0_Ew(prefices, modrm, sib, displacement);
4815 break;
4817 case 0xd6: //SALC
4818 case 0xd7: // XLAT
4819 working.write(STORE0_AL); break;
4821 case 0xf20: //MOV Rd, Cd
4822 case 0xf21: //MOV Rd, Dd
4823 store0_Rd(modrm); break;
4825 case 0xf22: store0_Cd(modrm); break; //MOV Cd, Rd
4826 case 0xf23: store0_Dd(modrm); break; //MOV Dd, Rd
4828 case 0xf31: //RDTSC
4829 case 0xf32: //RDMSR
4830 working.write(STORE0_EAX);
4831 working.write(STORE1_EDX);
4832 break;
4834 case 0xfa1: //POP FS
4835 working.write(STORE0_FS); break;
4837 case 0xfa9: //POP GS
4838 working.write(STORE0_GS); break;
4840 case 0xfab: //BTS Ev, Gv
4841 case 0xfb3: //BTR Ev, Gv
4842 case 0xfbb: //BTC Ev, Gv
4843 if ((prefices & PREFICES_OPERAND) != 0) {
4844 if ((modrm & 0xc0) == 0xc0)
4845 store0_Ed(prefices, modrm, sib, displacement);
4846 } else {
4847 if ((modrm & 0xc0) == 0xc0)
4848 store0_Ew(prefices, modrm, sib, displacement);
4850 break;
4852 case 0xfba: //Grp 8 Ev, Ib
4853 switch (modrm & 0x38) {
4854 case 0x28:
4855 case 0x30:
4856 case 0x38:
4857 if ((prefices & PREFICES_OPERAND) != 0) {
4858 if ((modrm & 0xc0) == 0xc0)
4859 store0_Ed(prefices, modrm, sib, displacement);
4860 } else {
4861 if ((modrm & 0xc0) == 0xc0)
4862 store0_Ew(prefices, modrm, sib, displacement);
4864 break;
4865 } break;
4867 case 0xfc8: working.write(STORE0_EAX); break; //BSWAP EAX
4868 case 0xfc9: working.write(STORE0_ECX); break; //BSWAP ECX
4869 case 0xfca: working.write(STORE0_EDX); break; //BSWAP EDX
4870 case 0xfcb: working.write(STORE0_EBX); break; //BSWAP EBX
4871 case 0xfcc: working.write(STORE0_ESP); break; //BSWAP ESP
4872 case 0xfcd: working.write(STORE0_EBP); break; //BSWAP EBP
4873 case 0xfce: working.write(STORE0_ESI); break; //BSWAP ESI
4874 case 0xfcf: working.write(STORE0_EDI); break; //BSWAP EDI
4876 case 0xd800:
4877 switch (modrm & 0x38)
4879 case 0x00:
4880 case 0x08:
4881 case 0x20:
4882 case 0x28:
4883 case 0x30:
4884 case 0x38:
4885 working.write(FSTORE0_ST0);
4886 working.write(FCHECK0);
4887 break;
4888 case 0x10: break;
4889 case 0x18: working.write(FPOP); break;
4891 break;
4893 case 0xd900:
4894 if ((modrm & 0xc0) != 0xc0)
4896 switch (modrm & 0x38)
4898 case 0x00:
4899 case 0x20:
4900 case 0x30:
4901 break;
4902 case 0x10:
4903 decodeM(prefices, modrm, sib, displacement);
4904 working.write(FSTORE0_MEM_SINGLE);
4905 break;
4906 case 0x18:
4907 decodeM(prefices, modrm, sib, displacement);
4908 working.write(FSTORE0_MEM_SINGLE);
4909 working.write(FPOP);
4910 break;
4911 case 0x28: working.write(STORE0_FPUCW); break;
4912 case 0x38:
4913 decodeM(prefices, modrm, sib, displacement);
4914 working.write(STORE0_MEM_WORD);
4915 break;
4918 else
4920 switch (modrm & 0xf8)
4922 case 0xc0: break;
4923 case 0xc8:
4924 working.write(FSTORE0_STN);
4925 working.write(modrm & 0x07);
4926 working.write(FSTORE1_ST0);
4927 break;
4929 switch (modrm)
4931 case 0xd0:
4932 case 0xe4:
4933 case 0xe5:
4934 case 0xe8:
4935 case 0xe9:
4936 case 0xea:
4937 case 0xeb:
4938 case 0xec:
4939 case 0xed:
4940 case 0xee:
4941 case 0xf6:
4942 case 0xf7: break;
4943 case 0xe0:
4944 case 0xe1:
4945 case 0xfe:
4946 case 0xff: working.write(FSTORE0_ST0); break;
4947 case 0xf0:
4948 case 0xf5:
4949 case 0xf8:
4950 case 0xfa:
4951 case 0xfc:
4952 case 0xfd:
4953 working.write(FSTORE0_ST0);
4954 working.write(FCHECK0);
4955 break;
4956 case 0xf2:
4957 working.write(FSTORE0_ST0);
4958 working.write(FLOAD0_1);
4959 working.write(FPUSH);
4960 break;
4961 case 0xf1:
4962 case 0xf3:
4963 working.write(FPOP);
4964 working.write(FSTORE0_ST0);
4965 break;
4966 case 0xf9:
4967 working.write(FPOP);
4968 working.write(FSTORE0_ST0);
4969 working.write(FCHECK0);
4970 break;
4971 case 0xf4:
4972 working.write(FSTORE1_ST0);
4973 working.write(FPUSH);
4974 break;
4975 case 0xfb:
4976 working.write(FSTORE1_ST0);
4977 working.write(FPUSH);
4978 working.write(FCHECK0);
4979 working.write(FCHECK1);
4980 break;
4983 break;
4985 case 0xda00:
4986 if ((modrm & 0xc0) != 0xc0)
4988 switch (modrm & 0x38)
4990 case 0x00:
4991 case 0x08:
4992 case 0x20:
4993 case 0x28:
4994 case 0x30:
4995 case 0x38:
4996 working.write(FSTORE0_ST0);
4997 working.write(FCHECK0);
4998 break;
4999 case 0x10: break;
5000 case 0x18: working.write(FPOP); break;
5003 else
5005 switch (modrm)
5007 case 0xe9:
5008 working.write(FPOP);
5009 working.write(FPOP);
5010 break;
5013 break;
5015 case 0xdb00:
5016 if ((modrm & 0xc0) != 0xc0)
5018 switch (modrm & 0x38)
5020 case 0x00:
5021 case 0x28: break;
5022 case 0x10:
5023 decodeM(prefices, modrm, sib, displacement);
5024 working.write(STORE0_MEM_DWORD);
5025 break;
5026 case 0x08:
5027 case 0x18:
5028 decodeM(prefices, modrm, sib, displacement);
5029 working.write(STORE0_MEM_DWORD);
5030 working.write(FPOP);
5031 break;
5032 case 0x38:
5033 decodeM(prefices, modrm, sib, displacement);
5034 working.write(FSTORE0_MEM_EXTENDED);
5035 working.write(FPOP);
5036 break;
5039 break;
5041 case 0xdc00:
5042 if ((modrm & 0xc0) != 0xc0)
5044 switch (modrm & 0x38)
5046 case 0x00:
5047 case 0x08:
5048 case 0x20:
5049 case 0x28:
5050 case 0x30:
5051 case 0x38:
5052 working.write(FSTORE0_ST0);
5053 working.write(FCHECK0);
5054 break;
5055 case 0x10: break;
5056 case 0x18: working.write(FPOP); break;
5059 else
5061 switch (modrm & 0xf8)
5063 case 0xc0:
5064 case 0xc8:
5065 case 0xe0:
5066 case 0xe8:
5067 case 0xf0:
5068 case 0xf8:
5069 working.write(FSTORE0_STN);
5070 working.write(modrm & 0x07);
5071 working.write(FCHECK0);
5072 break;
5075 break;
5077 case 0xdd00:
5078 if ((modrm & 0xc0) != 0xc0)
5080 switch (modrm & 0x38)
5082 case 0x00:
5083 case 0x20:
5084 case 0x30: break;
5085 case 0x08:
5086 decodeM(prefices, modrm, sib, displacement);
5087 working.write(STORE0_MEM_QWORD);
5088 working.write(FPOP);
5089 break;
5090 case 0x10:
5091 decodeM(prefices, modrm, sib, displacement);
5092 working.write(FSTORE0_MEM_DOUBLE);
5093 break;
5094 case 0x18:
5095 decodeM(prefices, modrm, sib, displacement);
5096 working.write(FSTORE0_MEM_DOUBLE);
5097 working.write(FPOP);
5098 break;
5099 case 0x38:
5100 decodeM(prefices, modrm, sib, displacement);
5101 working.write(STORE0_MEM_WORD);
5102 break;
5105 else
5107 switch (modrm & 0xf8)
5109 case 0xc0:
5110 case 0xe0: break;
5111 case 0xd0:
5112 working.write(FSTORE0_STN);
5113 working.write(modrm & 0x07);
5114 break;
5115 case 0xd8:
5116 working.write(FSTORE0_STN);
5117 working.write(modrm & 0x07);
5118 working.write(FPOP);
5119 break;
5120 case 0xe8: working.write(FPOP); break;
5123 break;
5125 case 0xde00:
5126 if ((modrm & 0xc0) != 0xc0)
5128 switch (modrm & 0x38)
5130 case 0x00:
5131 case 0x08:
5132 case 0x20:
5133 case 0x28:
5134 case 0x30:
5135 case 0x38:
5136 working.write(FSTORE0_ST0);
5137 working.write(FCHECK0);
5138 break;
5139 case 0x10: break;
5140 case 0x18: working.write(FPOP); break;
5143 else
5145 switch (modrm & 0xf8)
5147 case 0xc0:
5148 case 0xc8:
5149 case 0xe0:
5150 case 0xe8:
5151 case 0xf0:
5152 case 0xf8:
5153 working.write(FSTORE0_STN);
5154 working.write(modrm & 0x07);
5155 working.write(FPOP);
5156 working.write(FCHECK0);
5157 break;
5158 case 0xd0:
5159 case 0xd8: break;
5161 switch (modrm)
5163 case 0xd9:
5164 working.write(FPOP);
5165 working.write(FPOP);
5166 break;
5169 break;
5171 case 0xdf00:
5172 if ((modrm & 0xc0) != 0xc0)
5174 switch (modrm & 0x38)
5176 case 0x00:
5177 case 0x20:
5178 case 0x28:
5179 case 0x30: break;
5180 case 0x08:
5181 case 0x18:
5182 decodeM(prefices, modrm, sib, displacement);
5183 working.write(STORE0_MEM_WORD);
5184 working.write(FPOP);
5185 break;
5186 case 0x10:
5187 decodeM(prefices, modrm, sib, displacement);
5188 working.write(STORE0_MEM_WORD);
5189 break;
5190 case 0x38:
5191 decodeM(prefices, modrm, sib, displacement);
5192 working.write(STORE0_MEM_QWORD);
5193 working.write(FPOP);
5194 break;
5197 else
5199 switch (modrm & 0xf8)
5201 case 0xe8:
5202 case 0xf0: working.write(FPOP); break;
5204 switch (modrm)
5206 case 0xe0: working.write(STORE0_AX); break;
5209 break;
5214 private static int operationHasImmediate(int prefices, int opcode, int modrm)
5216 switch (opcode) {
5217 case 0x04: //ADD AL, Ib
5218 case 0x0c: //OR AL, Ib
5219 case 0x14: //ADC AL, Ib
5220 case 0x1c: //SBB AL, Ib
5221 case 0x24: //AND AL, Ib
5222 case 0x2c: //SUB AL, Ib
5223 case 0x34: //XOR AL, Ib
5224 case 0x3c: //CMP AL, Ib
5225 case 0x6a: //PUSH Ib
5226 case 0x6b: //IMUL Gv, Ev, Ib
5227 case 0x70: //Jcc Jb
5228 case 0x71:
5229 case 0x72:
5230 case 0x73:
5231 case 0x74:
5232 case 0x75:
5233 case 0x76:
5234 case 0x77:
5235 case 0x78:
5236 case 0x79:
5237 case 0x7a:
5238 case 0x7b:
5239 case 0x7c:
5240 case 0x7d:
5241 case 0x7e:
5242 case 0x7f:
5243 case 0x80: //IMM G1 Eb, Ib
5244 case 0x82: //IMM G1 Eb, Ib
5245 case 0x83: //IMM G1 Ev, Ib
5246 case 0xa8: //TEST AL, Ib
5247 case 0xb0: //MOV AL, Ib
5248 case 0xb1: //MOV CL, Ib
5249 case 0xb2: //MOV DL, Ib
5250 case 0xb3: //MOV BL, Ib
5251 case 0xb4: //MOV AH, Ib
5252 case 0xb5: //MOV CH, Ib
5253 case 0xb6: //MOV DH, Ib
5254 case 0xb7: //MOV BH, Ib
5255 case 0xc0: //SFT G2 Eb, Ib
5256 case 0xc1: //SFT G2 Ev, Ib
5257 case 0xc6: //MOV G11 Eb, Ib
5258 case 0xcd: //INT Ib
5259 case 0xd4: //AAM Ib
5260 case 0xd5: //AAD Ib
5261 case 0xe0: //LOOPNZ Jb
5262 case 0xe1: //LOOPZ Jb
5263 case 0xe2: //LOOP Jb
5264 case 0xe3: //JCXZ Jb
5265 case 0xe4: //IN AL, Ib
5266 case 0xe5: //IN eAX, Ib
5267 case 0xe6: //OUT Ib, AL
5268 case 0xe7: //OUT Ib, eAX
5269 case 0xeb: //JMP Jb
5270 case 0xfa4: //SHLD Ev, Gv, Ib
5271 case 0xfac: //SHRD Ev, Gv, Ib
5272 case 0xfba: //Grp 8 Ev, Ib
5273 return 1;
5275 case 0xc2: //RET Iw
5276 case 0xca: //RETF Iw
5277 return 2;
5279 case 0xc8: //ENTER Iw, Ib
5280 return 3;
5282 case 0x05: //ADD eAX, Iv
5283 case 0x0d: //OR eAX, Iv
5284 case 0x15: //ADC eAX, Iv
5285 case 0x1d: //SBB eAX, Iv
5286 case 0x25: //AND eAX, Iv
5287 case 0x2d: //SUB eAX, Iv
5288 case 0x35: //XOR eAX, Iv
5289 case 0x3d: //CMP eAX, Iv
5290 case 0x68: //PUSH Iv
5291 case 0x69: //IMUL Gv, Ev, Iv
5292 case 0x81: //IMM G1 Ev, Iv
5293 case 0xa9: //TEST eAX, Iv
5294 case 0xb8: //MOV eAX, Iv
5295 case 0xb9: //MOV eCX, Iv
5296 case 0xba: //MOV eDX, Iv
5297 case 0xbb: //MOV eBX, Iv
5298 case 0xbc: //MOV eSP, Iv
5299 case 0xbd: //MOV eBP, Iv
5300 case 0xbe: //MOV eSI, Iv
5301 case 0xbf: //MOV eDI, Iv
5302 case 0xc7: //MOV G11 Ev, Iv
5303 case 0xe8: //CALL Jv
5304 case 0xe9: //JMP Jv
5305 case 0xf80: //JO Jv
5306 case 0xf81: //JNO Jv
5307 case 0xf82: //JC Jv
5308 case 0xf83: //JNC Jv
5309 case 0xf84: //JZ Jv
5310 case 0xf85: //JNZ Jv
5311 case 0xf86: //JNA Jv
5312 case 0xf87: //JA Jv
5313 case 0xf88: //JS Jv
5314 case 0xf89: //JNS Jv
5315 case 0xf8a: //JP Jv
5316 case 0xf8b: //JNP Jv
5317 case 0xf8c: //JL Jv
5318 case 0xf8d: //JNL Jv
5319 case 0xf8e: //JNG Jv
5320 case 0xf8f: //JG Jv
5321 if ((prefices & PREFICES_OPERAND) != 0)
5322 return 4;
5323 else
5324 return 2;
5326 case 0x9a: //CALLF Ap
5327 case 0xea: //JMPF Ap
5328 if ((prefices & PREFICES_OPERAND) != 0)
5329 return 6;
5330 else
5331 return 4;
5333 case 0xf6: //UNA G3 Eb, ?
5334 switch (modrm & 0x38) {
5335 case 0x00: //TEST Eb, Ib
5336 return 1;
5337 default:
5338 return 0;
5341 case 0xf7: //UNA G3 Ev, ?
5342 switch (modrm & 0x38) {
5343 case 0x00: //TEST Ev, Iv
5344 if ((prefices & PREFICES_OPERAND) != 0)
5345 return 4;
5346 else
5347 return 2;
5348 default:
5349 return 0;
5352 return 0;
5355 private static int operationHasDisplacement(int prefices, int opcode, int modrm, int sib)
5357 switch (opcode) {
5358 //modrm things
5359 case 0x00: //ADD Eb, Gb
5360 case 0x01: //ADD Ev, Gv
5361 case 0x02: //ADD Gb, Eb
5362 case 0x03: //ADD Gv, Ev
5363 case 0x08: //OR Eb, Gb
5364 case 0x09: //OR Ev, Gv
5365 case 0x0a: //OR Gb, Eb
5366 case 0x0b: //OR Gv, Ev
5367 case 0x10: //ADC Eb, Gb
5368 case 0x11: //ADC Ev, Gv
5369 case 0x12: //ADC Gb, Eb
5370 case 0x13: //ADC Gv, Ev
5371 case 0x18: //SBB Eb, Gb
5372 case 0x19: //SBB Ev, Gv
5373 case 0x1a: //SBB Gb, Eb
5374 case 0x1b: //SBB Gv, Ev
5375 case 0x20: //AND Eb, Gb
5376 case 0x21: //AND Ev, Gv
5377 case 0x22: //AND Gb, Eb
5378 case 0x23: //AND Gv, Ev
5379 case 0x28: //SUB Eb, Gb
5380 case 0x29: //SUB Ev, Gv
5381 case 0x2a: //SUB Gb, Eb
5382 case 0x2b: //SUB Gv, Ev
5383 case 0x30: //XOR Eb, Gb
5384 case 0x31: //XOR Ev, Gv
5385 case 0x32: //XOR Gb, Eb
5386 case 0x33: //XOR Gv, Ev
5387 case 0x38: //CMP Eb, Gb
5388 case 0x39: //CMP Ev, Gv
5389 case 0x3a: //CMP Gb, Eb
5390 case 0x3b: //CMP Gv, Ev
5391 case 0x62: //BOUND Gv, Ma
5392 case 0x69: //IMUL Gv, Ev, Iv
5393 case 0x6b: //IMUL Gv, Ev, Ib
5394 case 0x80: //IMM G1 Eb, Ib
5395 case 0x81: //IMM G1 Ev, Iv
5396 case 0x82: //IMM G1 Eb, Ib
5397 case 0x83: //IMM G1 Ev, Ib
5398 case 0x84: //TEST Eb, Gb
5399 case 0x85: //TEST Ev, Gv
5400 case 0x86: //XCHG Eb, Gb
5401 case 0x87: //XCHG Ev, Gv
5402 case 0x88: //MOV Eb, Gb
5403 case 0x89: //MOV Ev, Gv
5404 case 0x8a: //MOV Gb, Eb
5405 case 0x8b: //MOV Gv, Ev
5406 case 0x8c: //MOV Ew, Sw
5407 case 0x8d: //LEA Gv, M
5408 case 0x8e: //MOV Sw, Ew
5409 case 0x8f: //POP Ev
5410 case 0xc0: //SFT G2 Eb, Ib
5411 case 0xc1: //SFT G2 Ev, Ib
5412 case 0xc4: //LES Gv, Mp
5413 case 0xc5: //LDS Gv, Mp
5414 case 0xc6: //MOV G11 Eb, Ib
5415 case 0xc7: //MOV G11 Ev, Iv
5416 case 0xd0: //SFT G2 Eb, 1
5417 case 0xd1: //SFT G2 Ev, 1
5418 case 0xd2: //SFT G2 Eb, CL
5419 case 0xd3: //SFT G2 Ev, CL
5420 case 0xf6: //UNA G3 Eb, ?
5421 case 0xf7: //UNA G3 Ev, ?
5422 case 0xfe: //INC/DEC G4 Eb
5423 case 0xff: //INC/DEC G5
5425 case 0xf00: //Grp 6
5426 case 0xf01: //Grp 7
5428 case 0xf20: //MOV Rd, Cd
5429 case 0xf22: //MOV Cd, Rd
5431 case 0xf40: //CMOVO
5432 case 0xf41: //CMOVNO
5433 case 0xf42: //CMOVC
5434 case 0xf43: //CMOVNC
5435 case 0xf44: //CMOVZ
5436 case 0xf45: //CMOVNZ
5437 case 0xf46: //CMOVBE
5438 case 0xf47: //CMOVNBE
5439 case 0xf48: //CMOVS
5440 case 0xf49: //CMOVNS
5441 case 0xf4a: //CMOVP
5442 case 0xf4b: //CMOVNP
5443 case 0xf4c: //CMOVL
5444 case 0xf4d: //CMOVNL
5445 case 0xf4e: //CMOVLE
5446 case 0xf4f: //CMOVNLE
5448 case 0xf90: //SETO
5449 case 0xf91: //SETNO
5450 case 0xf92: //SETC
5451 case 0xf93: //SETNC
5452 case 0xf94: //SETZ
5453 case 0xf95: //SETNZ
5454 case 0xf96: //SETBE
5455 case 0xf97: //SETNBE
5456 case 0xf98: //SETS
5457 case 0xf99: //SETNS
5458 case 0xf9a: //SETP
5459 case 0xf9b: //SETNP
5460 case 0xf9c: //SETL
5461 case 0xf9d: //SETNL
5462 case 0xf9e: //SETLE
5463 case 0xf9f: //SETNLE
5465 case 0xfa3: //BT Ev, Gv
5466 case 0xfa4: //SHLD Ev, Gv, Ib
5467 case 0xfa5: //SHLD Ev, Gv, CL
5468 case 0xfab: //BTS Ev, Gv
5469 case 0xfac: //SHRD Ev, Gv, Ib
5470 case 0xfad: //SHRD Ev, Gv, CL
5472 case 0xfaf: //IMUL Gv, Ev
5474 case 0xfb0: //CMPXCHG Eb, Gb
5475 case 0xfb1: //CMPXCHG Ev, Gv
5476 case 0xfb2: //LSS Mp
5477 case 0xfb3: //BTR Ev, Gv
5478 case 0xfb4: //LFS Mp
5479 case 0xfb5: //LGS Mp
5480 case 0xfb6: //MOVZX Gv, Eb
5481 case 0xfb7: //MOVZX Gv, Ew
5483 case 0xfba: //Grp 8 Ev, Ib
5484 case 0xfbb: //BTC Ev, Gv
5485 case 0xfbc: //BSF Gv, Ev
5486 case 0xfbd: //BSR Gv, Ev
5487 case 0xfbe: //MOVSX Gv, Eb
5488 case 0xfbf: //MOVSX Gv, Ew
5489 case 0xfc0: //XADD Eb, Gb
5490 case 0xfc1: //XADD Ev, Gv
5491 return modrmHasDisplacement(prefices, modrm, sib);
5493 //From Input
5494 case 0xd800:
5495 case 0xd900:
5496 case 0xda00:
5497 case 0xdb00:
5498 case 0xdc00:
5499 case 0xdd00:
5500 case 0xde00:
5501 case 0xdf00:
5502 if ((modrm & 0xc0) != 0xc0)
5503 return modrmHasDisplacement(prefices, modrm, sib);
5504 else
5505 return 0;
5507 //special cases
5508 case 0xa0: //MOV AL, Ob
5509 case 0xa2: //MOV Ob, AL
5510 case 0xa1: //MOV eAX, Ov
5511 case 0xa3: //MOV Ov, eAX
5512 if ((prefices & PREFICES_ADDRESS) != 0)
5513 return 4;
5514 else
5515 return 2;
5517 default: return 0;
5522 private static int modrmHasDisplacement(int prefices, int modrm, int sib)
5524 if ((prefices & PREFICES_ADDRESS) != 0) {
5525 //32 bit address size
5526 switch(modrm & 0xc0) {
5527 case 0x00:
5528 switch (modrm & 0x7) {
5529 case 0x4:
5530 if ((sib & 0x7) == 0x5)
5531 return 4;
5532 else
5533 return 0;
5534 case 0x5: return 4;
5536 break;
5537 case 0x40: return 1; //IB
5538 case 0x80: return 4; //ID
5540 } else {
5541 //16 bit address size
5542 switch(modrm & 0xc0) {
5543 case 0x00:
5544 if ((modrm & 0x7) == 0x6)
5545 return 2;
5546 else
5547 return 0;
5548 case 0x40: return 1; //IB
5549 case 0x80: return 2; //IW
5553 return 0;
5556 public static boolean isFarJump(int opcode, int modrm)
5558 switch (opcode)
5560 case 0x9a: //CALLF Ap
5561 case 0xca: //RETF Iw
5562 case 0xcb: //RETF
5563 case 0xcc: //INT 3
5564 case 0xcd: //INT Ib
5565 case 0xce: //INTO
5566 case 0xcf: //IRET
5567 case 0xea: //JMPF Ap
5568 case 0xf1: //INT 1
5569 return true;
5571 case 0xff:
5572 switch (modrm & 0x38) {
5573 case 0x18: //CALLF Ep
5574 case 0x28: //JMPF Ep
5575 return true;
5576 default: return false;
5579 default:
5580 return false;
5584 public static boolean isNearJump(int opcode, int modrm)
5586 switch (opcode)
5588 case 0x70: //Jcc Jb
5589 case 0x71:
5590 case 0x72:
5591 case 0x73:
5592 case 0x74:
5593 case 0x75:
5594 case 0x76:
5595 case 0x77:
5596 case 0x78:
5597 case 0x79:
5598 case 0x7a:
5599 case 0x7b:
5600 case 0x7c:
5601 case 0x7d:
5602 case 0x7e:
5603 case 0x7f:
5604 case 0xc2: //RET Iw
5605 case 0xc3: //RET
5606 case 0xe0: //LOOPNZ Jb
5607 case 0xe1: //LOOPZ Jb
5608 case 0xe2: //LOOP Jb
5609 case 0xe3: //JCXZ Jb
5610 case 0xe8: //CALL Jv
5611 case 0xe9: //JMP Jv
5612 case 0xeb: //JMP Jb
5613 return true;
5615 case 0xff:
5616 switch (modrm & 0x38) {
5617 case 0x10: //CALLN Ed
5618 case 0x20: //JMPN Ed
5619 return true;
5620 default: return false;
5623 case 0x0f80: //Jcc Jv
5624 case 0x0f81:
5625 case 0x0f82:
5626 case 0x0f83:
5627 case 0x0f84:
5628 case 0x0f85:
5629 case 0x0f86:
5630 case 0x0f87:
5631 case 0x0f88:
5632 case 0x0f89:
5633 case 0x0f8a:
5634 case 0x0f8b:
5635 case 0x0f8c:
5636 case 0x0f8d:
5637 case 0x0f8e:
5638 case 0x0f8f:
5639 return true;
5640 default:
5641 return false;
5645 public static boolean isModeSwitch(int opcode, int modrm)
5647 switch (opcode) {
5648 case 0x0f22: //MOV Cd, Ed
5649 return true;
5650 case 0x0f01: //LMSW
5651 return ((modrm & 0x38) == 0x30);
5652 default:
5653 return false;
5657 public static boolean isBlockTerminating(int opcode, int modrm)
5659 switch (opcode) {
5660 case 0x63: //ARPL
5661 case 0xf4: //HLT
5662 return true;
5663 default:
5664 return false;
5668 public static boolean isJump(int opcode, int modrm)
5670 return isNearJump(opcode, modrm) || isFarJump(opcode, modrm) || isModeSwitch(opcode, modrm) || isBlockTerminating(opcode, modrm);
5673 private void store0_Cd(int modrm)
5675 switch(modrm & 0x38) {
5676 case 0x00: working.write(STORE0_CR0); break;
5677 case 0x10: working.write(STORE0_CR2); break;
5678 case 0x18: working.write(STORE0_CR3); break;
5679 case 0x20: working.write(STORE0_CR4); break;
5680 default: throw new IllegalStateException("Unknown Control Register Operand");
5684 private void load0_Cd(int modrm)
5686 switch(modrm & 0x38) {
5687 case 0x00: working.write(LOAD0_CR0); break;
5688 case 0x10: working.write(LOAD0_CR2); break;
5689 case 0x18: working.write(LOAD0_CR3); break;
5690 case 0x20: working.write(LOAD0_CR4); break;
5691 default: throw new IllegalStateException("Unknown Control Register Operand "+ modrm);
5695 private void store0_Dd(int modrm)
5697 switch(modrm & 0x38) {
5698 case 0x00: working.write(STORE0_DR0); break;
5699 case 0x08: working.write(STORE0_DR1); break;
5700 case 0x10: working.write(STORE0_DR2); break;
5701 case 0x18: working.write(STORE0_DR3); break;
5702 case 0x30: working.write(STORE0_DR6); break;
5703 case 0x38: working.write(STORE0_DR7); break;
5704 default: throw new IllegalStateException("Unknown Debug Register Operand");
5708 private void load0_Dd(int modrm)
5710 switch(modrm & 0x38) {
5711 case 0x00: working.write(LOAD0_DR0); break;
5712 case 0x08: working.write(LOAD0_DR1); break;
5713 case 0x10: working.write(LOAD0_DR2); break;
5714 case 0x18: working.write(LOAD0_DR3); break;
5715 case 0x30: working.write(LOAD0_DR6); break;
5716 case 0x38: working.write(LOAD0_DR7); break;
5717 default: throw new IllegalStateException("Unknown Debug Register Operand");
5721 private void load0_Eb(int prefices, int modrm, int sib, int displacement)
5723 switch(modrm & 0xc7) {
5724 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_BYTE); break;
5726 case 0xc0: working.write(LOAD0_AL); break;
5727 case 0xc1: working.write(LOAD0_CL); break;
5728 case 0xc2: working.write(LOAD0_DL); break;
5729 case 0xc3: working.write(LOAD0_BL); break;
5730 case 0xc4: working.write(LOAD0_AH); break;
5731 case 0xc5: working.write(LOAD0_CH); break;
5732 case 0xc6: working.write(LOAD0_DH); break;
5733 case 0xc7: working.write(LOAD0_BH); break;
5736 private void load1_Eb(int prefices, int modrm, int sib, int displacement)
5738 switch(modrm & 0xc7) {
5739 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD1_MEM_BYTE); break;
5741 case 0xc0: working.write(LOAD1_AL); break;
5742 case 0xc1: working.write(LOAD1_CL); break;
5743 case 0xc2: working.write(LOAD1_DL); break;
5744 case 0xc3: working.write(LOAD1_BL); break;
5745 case 0xc4: working.write(LOAD1_AH); break;
5746 case 0xc5: working.write(LOAD1_CH); break;
5747 case 0xc6: working.write(LOAD1_DH); break;
5748 case 0xc7: working.write(LOAD1_BH); break;
5751 private void store0_Eb(int prefices, int modrm, int sib, int displacement)
5753 switch(modrm & 0xc7) {
5754 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_BYTE); break;
5756 case 0xc0: working.write(STORE0_AL); break;
5757 case 0xc1: working.write(STORE0_CL); break;
5758 case 0xc2: working.write(STORE0_DL); break;
5759 case 0xc3: working.write(STORE0_BL); break;
5760 case 0xc4: working.write(STORE0_AH); break;
5761 case 0xc5: working.write(STORE0_CH); break;
5762 case 0xc6: working.write(STORE0_DH); break;
5763 case 0xc7: working.write(STORE0_BH); break;
5766 private void store1_Eb(int prefices, int modrm, int sib, int displacement)
5768 switch(modrm & 0xc7) {
5769 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE1_MEM_BYTE); break;
5771 case 0xc0: working.write(STORE1_AL); break;
5772 case 0xc1: working.write(STORE1_CL); break;
5773 case 0xc2: working.write(STORE1_DL); break;
5774 case 0xc3: working.write(STORE1_BL); break;
5775 case 0xc4: working.write(STORE1_AH); break;
5776 case 0xc5: working.write(STORE1_CH); break;
5777 case 0xc6: working.write(STORE1_DH); break;
5778 case 0xc7: working.write(STORE1_BH); break;
5782 private void load0_Ew(int prefices, int modrm, int sib, int displacement)
5784 switch (modrm & 0xc7) {
5785 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_WORD); break;
5787 case 0xc0: working.write(LOAD0_AX); break;
5788 case 0xc1: working.write(LOAD0_CX); break;
5789 case 0xc2: working.write(LOAD0_DX); break;
5790 case 0xc3: working.write(LOAD0_BX); break;
5791 case 0xc4: working.write(LOAD0_SP); break;
5792 case 0xc5: working.write(LOAD0_BP); break;
5793 case 0xc6: working.write(LOAD0_SI); break;
5794 case 0xc7: working.write(LOAD0_DI); break;
5797 private void store0_Ew(int prefices, int modrm, int sib, int displacement)
5799 switch (modrm & 0xc7) {
5800 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_WORD); break;
5802 case 0xc0: working.write(STORE0_AX); break;
5803 case 0xc1: working.write(STORE0_CX); break;
5804 case 0xc2: working.write(STORE0_DX); break;
5805 case 0xc3: working.write(STORE0_BX); break;
5806 case 0xc4: working.write(STORE0_SP); break;
5807 case 0xc5: working.write(STORE0_BP); break;
5808 case 0xc6: working.write(STORE0_SI); break;
5809 case 0xc7: working.write(STORE0_DI); break;
5812 private void load1_Ew(int prefices, int modrm, int sib, int displacement)
5814 switch (modrm & 0xc7) {
5815 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD1_MEM_WORD); break;
5817 case 0xc0: working.write(LOAD1_AX); break;
5818 case 0xc1: working.write(LOAD1_CX); break;
5819 case 0xc2: working.write(LOAD1_DX); break;
5820 case 0xc3: working.write(LOAD1_BX); break;
5821 case 0xc4: working.write(LOAD1_SP); break;
5822 case 0xc5: working.write(LOAD1_BP); break;
5823 case 0xc6: working.write(LOAD1_SI); break;
5824 case 0xc7: working.write(LOAD1_DI); break;
5827 private void store1_Ew(int prefices, int modrm, int sib, int displacement)
5829 switch (modrm & 0xc7) {
5830 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE1_MEM_WORD); break;
5832 case 0xc0: working.write(STORE1_AX); break;
5833 case 0xc1: working.write(STORE1_CX); break;
5834 case 0xc2: working.write(STORE1_DX); break;
5835 case 0xc3: working.write(STORE1_BX); break;
5836 case 0xc4: working.write(STORE1_SP); break;
5837 case 0xc5: working.write(STORE1_BP); break;
5838 case 0xc6: working.write(STORE1_SI); break;
5839 case 0xc7: working.write(STORE1_DI); break;
5843 private void load0_Ed(int prefices, int modrm, int sib, int displacement)
5845 switch (modrm & 0xc7) {
5846 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_DWORD); break;
5848 case 0xc0: working.write(LOAD0_EAX); break;
5849 case 0xc1: working.write(LOAD0_ECX); break;
5850 case 0xc2: working.write(LOAD0_EDX); break;
5851 case 0xc3: working.write(LOAD0_EBX); break;
5852 case 0xc4: working.write(LOAD0_ESP); break;
5853 case 0xc5: working.write(LOAD0_EBP); break;
5854 case 0xc6: working.write(LOAD0_ESI); break;
5855 case 0xc7: working.write(LOAD0_EDI); break;
5859 private void store0_Ed(int prefices, int modrm, int sib, int displacement)
5861 switch (modrm & 0xc7) {
5862 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE0_MEM_DWORD); break;
5864 case 0xc0: working.write(STORE0_EAX); break;
5865 case 0xc1: working.write(STORE0_ECX); break;
5866 case 0xc2: working.write(STORE0_EDX); break;
5867 case 0xc3: working.write(STORE0_EBX); break;
5868 case 0xc4: working.write(STORE0_ESP); break;
5869 case 0xc5: working.write(STORE0_EBP); break;
5870 case 0xc6: working.write(STORE0_ESI); break;
5871 case 0xc7: working.write(STORE0_EDI); break;
5874 private void load1_Ed(int prefices, int modrm, int sib, int displacement)
5876 switch (modrm & 0xc7) {
5877 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD1_MEM_DWORD); break;
5879 case 0xc0: working.write(LOAD1_EAX); break;
5880 case 0xc1: working.write(LOAD1_ECX); break;
5881 case 0xc2: working.write(LOAD1_EDX); break;
5882 case 0xc3: working.write(LOAD1_EBX); break;
5883 case 0xc4: working.write(LOAD1_ESP); break;
5884 case 0xc5: working.write(LOAD1_EBP); break;
5885 case 0xc6: working.write(LOAD1_ESI); break;
5886 case 0xc7: working.write(LOAD1_EDI); break;
5890 private void store1_Ed(int prefices, int modrm, int sib, int displacement)
5892 switch (modrm & 0xc7) {
5893 default: decodeM(prefices, modrm, sib, displacement); working.write(STORE1_MEM_DWORD); break;
5895 case 0xc0: working.write(STORE1_EAX); break;
5896 case 0xc1: working.write(STORE1_ECX); break;
5897 case 0xc2: working.write(STORE1_EDX); break;
5898 case 0xc3: working.write(STORE1_EBX); break;
5899 case 0xc4: working.write(STORE1_ESP); break;
5900 case 0xc5: working.write(STORE1_EBP); break;
5901 case 0xc6: working.write(STORE1_ESI); break;
5902 case 0xc7: working.write(STORE1_EDI); break;
5906 private void load0_Eq(int prefices, int modrm, int sib, int displacement)
5908 switch (modrm & 0xc7) {
5909 default: decodeM(prefices, modrm, sib, displacement); working.write(LOAD0_MEM_QWORD); break;
5911 case 0xc1:
5912 case 0xc2:
5913 case 0xc3:
5914 case 0xc4:
5915 case 0xc5:
5916 case 0xc6:
5917 case 0xc7:
5918 throw new IllegalStateException("There are no 64bit GP Registers");
5922 private void load0_Gb(int modrm)
5924 switch(modrm & 0x38) {
5925 case 0x00: working.write(LOAD0_AL); break;
5926 case 0x08: working.write(LOAD0_CL); break;
5927 case 0x10: working.write(LOAD0_DL); break;
5928 case 0x18: working.write(LOAD0_BL); break;
5929 case 0x20: working.write(LOAD0_AH); break;
5930 case 0x28: working.write(LOAD0_CH); break;
5931 case 0x30: working.write(LOAD0_DH); break;
5932 case 0x38: working.write(LOAD0_BH); break;
5933 default: throw new IllegalStateException("Unknown Byte Register Operand");
5936 private void store0_Gb(int modrm)
5938 switch(modrm & 0x38) {
5939 case 0x00: working.write(STORE0_AL); break;
5940 case 0x08: working.write(STORE0_CL); break;
5941 case 0x10: working.write(STORE0_DL); break;
5942 case 0x18: working.write(STORE0_BL); break;
5943 case 0x20: working.write(STORE0_AH); break;
5944 case 0x28: working.write(STORE0_CH); break;
5945 case 0x30: working.write(STORE0_DH); break;
5946 case 0x38: working.write(STORE0_BH); break;
5947 default: throw new IllegalStateException("Unknown Byte Register Operand");
5950 private void load1_Gb(int modrm)
5952 switch(modrm & 0x38) {
5953 case 0x00: working.write(LOAD1_AL); break;
5954 case 0x08: working.write(LOAD1_CL); break;
5955 case 0x10: working.write(LOAD1_DL); break;
5956 case 0x18: working.write(LOAD1_BL); break;
5957 case 0x20: working.write(LOAD1_AH); break;
5958 case 0x28: working.write(LOAD1_CH); break;
5959 case 0x30: working.write(LOAD1_DH); break;
5960 case 0x38: working.write(LOAD1_BH); break;
5961 default: throw new IllegalStateException("Unknown Byte Register Operand");
5964 private void store1_Gb(int modrm)
5966 switch(modrm & 0x38) {
5967 case 0x00: working.write(STORE1_AL); break;
5968 case 0x08: working.write(STORE1_CL); break;
5969 case 0x10: working.write(STORE1_DL); break;
5970 case 0x18: working.write(STORE1_BL); break;
5971 case 0x20: working.write(STORE1_AH); break;
5972 case 0x28: working.write(STORE1_CH); break;
5973 case 0x30: working.write(STORE1_DH); break;
5974 case 0x38: working.write(STORE1_BH); break;
5975 default: throw new IllegalStateException("Unknown Byte Register Operand");
5979 private void load0_Gw(int modrm)
5981 switch(modrm & 0x38) {
5982 case 0x00: working.write(LOAD0_AX); break;
5983 case 0x08: working.write(LOAD0_CX); break;
5984 case 0x10: working.write(LOAD0_DX); break;
5985 case 0x18: working.write(LOAD0_BX); break;
5986 case 0x20: working.write(LOAD0_SP); break;
5987 case 0x28: working.write(LOAD0_BP); break;
5988 case 0x30: working.write(LOAD0_SI); break;
5989 case 0x38: working.write(LOAD0_DI); break;
5990 default: throw new IllegalStateException("Unknown Word Register Operand");
5993 private void store0_Gw(int modrm)
5995 switch(modrm & 0x38) {
5996 case 0x00: working.write(STORE0_AX); break;
5997 case 0x08: working.write(STORE0_CX); break;
5998 case 0x10: working.write(STORE0_DX); break;
5999 case 0x18: working.write(STORE0_BX); break;
6000 case 0x20: working.write(STORE0_SP); break;
6001 case 0x28: working.write(STORE0_BP); break;
6002 case 0x30: working.write(STORE0_SI); break;
6003 case 0x38: working.write(STORE0_DI); break;
6004 default: throw new IllegalStateException("Unknown Word Register Operand");
6007 private void load1_Gw(int modrm)
6009 switch(modrm & 0x38) {
6010 case 0x00: working.write(LOAD1_AX); break;
6011 case 0x08: working.write(LOAD1_CX); break;
6012 case 0x10: working.write(LOAD1_DX); break;
6013 case 0x18: working.write(LOAD1_BX); break;
6014 case 0x20: working.write(LOAD1_SP); break;
6015 case 0x28: working.write(LOAD1_BP); break;
6016 case 0x30: working.write(LOAD1_SI); break;
6017 case 0x38: working.write(LOAD1_DI); break;
6018 default: throw new IllegalStateException("Unknown Word Register Operand");
6021 private void store1_Gw(int modrm)
6023 switch(modrm & 0x38) {
6024 case 0x00: working.write(STORE1_AX); break;
6025 case 0x08: working.write(STORE1_CX); break;
6026 case 0x10: working.write(STORE1_DX); break;
6027 case 0x18: working.write(STORE1_BX); break;
6028 case 0x20: working.write(STORE1_SP); break;
6029 case 0x28: working.write(STORE1_BP); break;
6030 case 0x30: working.write(STORE1_SI); break;
6031 case 0x38: working.write(STORE1_DI); break;
6032 default: throw new IllegalStateException("Unknown Word Register Operand");
6036 private void load0_Gd(int modrm)
6038 switch(modrm & 0x38) {
6039 case 0x00: working.write(LOAD0_EAX); break;
6040 case 0x08: working.write(LOAD0_ECX); break;
6041 case 0x10: working.write(LOAD0_EDX); break;
6042 case 0x18: working.write(LOAD0_EBX); break;
6043 case 0x20: working.write(LOAD0_ESP); break;
6044 case 0x28: working.write(LOAD0_EBP); break;
6045 case 0x30: working.write(LOAD0_ESI); break;
6046 case 0x38: working.write(LOAD0_EDI); break;
6047 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6050 private void store0_Gd(int modrm)
6052 switch(modrm & 0x38) {
6053 case 0x00: working.write(STORE0_EAX); break;
6054 case 0x08: working.write(STORE0_ECX); break;
6055 case 0x10: working.write(STORE0_EDX); break;
6056 case 0x18: working.write(STORE0_EBX); break;
6057 case 0x20: working.write(STORE0_ESP); break;
6058 case 0x28: working.write(STORE0_EBP); break;
6059 case 0x30: working.write(STORE0_ESI); break;
6060 case 0x38: working.write(STORE0_EDI); break;
6061 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6064 private void load1_Gd(int modrm)
6066 switch(modrm & 0x38) {
6067 case 0x00: working.write(LOAD1_EAX); break;
6068 case 0x08: working.write(LOAD1_ECX); break;
6069 case 0x10: working.write(LOAD1_EDX); break;
6070 case 0x18: working.write(LOAD1_EBX); break;
6071 case 0x20: working.write(LOAD1_ESP); break;
6072 case 0x28: working.write(LOAD1_EBP); break;
6073 case 0x30: working.write(LOAD1_ESI); break;
6074 case 0x38: working.write(LOAD1_EDI); break;
6075 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6078 private void store1_Gd(int modrm)
6080 switch(modrm & 0x38) {
6081 case 0x00: working.write(STORE1_EAX); break;
6082 case 0x08: working.write(STORE1_ECX); break;
6083 case 0x10: working.write(STORE1_EDX); break;
6084 case 0x18: working.write(STORE1_EBX); break;
6085 case 0x20: working.write(STORE1_ESP); break;
6086 case 0x28: working.write(STORE1_EBP); break;
6087 case 0x30: working.write(STORE1_ESI); break;
6088 case 0x38: working.write(STORE1_EDI); break;
6089 default: throw new IllegalStateException("Unknown DoubleWord Register Operand");
6093 private void load0_Sw(int modrm)
6095 switch(modrm & 0x38) {
6096 case 0x00: working.write(LOAD0_ES); break;
6097 case 0x08: working.write(LOAD0_CS); break;
6098 case 0x10: working.write(LOAD0_SS); break;
6099 case 0x18: working.write(LOAD0_DS); break;
6100 case 0x20: working.write(LOAD0_FS); break;
6101 case 0x28: working.write(LOAD0_GS); break;
6102 default: throw new IllegalStateException("Unknown Segment Register Operand");
6105 private void store0_Sw(int modrm)
6107 switch(modrm & 0x38) {
6108 case 0x00: working.write(STORE0_ES); break;
6109 case 0x08: working.write(STORE0_CS); break;
6110 case 0x10: working.write(STORE0_SS); break;
6111 case 0x18: working.write(STORE0_DS); break;
6112 case 0x20: working.write(STORE0_FS); break;
6113 case 0x28: working.write(STORE0_GS); break;
6114 default: throw new IllegalStateException("Unknown Segment Register Operand");
6117 private void decodeO(int prefices, int displacement)
6119 switch (prefices & PREFICES_SG) {
6120 default:
6121 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6122 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6123 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6124 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6125 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6126 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6129 if ((prefices & PREFICES_ADDRESS) != 0) {
6130 if (decodingAddressMode())
6131 working.write(ADDR_ID); working.write(displacement);
6132 } else {
6133 if (decodingAddressMode()) {
6134 working.write(ADDR_IW); working.write(displacement);
6135 working.write(ADDR_MASK16);
6140 private void load0_Ob(int prefices, int displacement)
6142 decodeO(prefices, displacement);
6143 working.write(LOAD0_MEM_BYTE);
6145 private void store0_Ob(int prefices, int displacement)
6147 decodeO(prefices, displacement);
6148 working.write(STORE0_MEM_BYTE);
6151 private void load0_Ow(int prefices, int displacement)
6153 decodeO(prefices, displacement);
6154 working.write(LOAD0_MEM_WORD);
6156 private void store0_Ow(int prefices, int displacement)
6158 decodeO(prefices, displacement);
6159 working.write(STORE0_MEM_WORD);
6162 private void load0_Od(int prefices, int displacement)
6164 decodeO(prefices, displacement);
6165 working.write(LOAD0_MEM_DWORD);
6167 private void store0_Od(int prefices, int displacement)
6169 decodeO(prefices, displacement);
6170 working.write(STORE0_MEM_DWORD);
6173 private void load0_M(int prefices, int modrm, int sib, int displacement)
6175 decodeM(prefices, modrm, sib, displacement);
6176 working.write(LOAD0_ADDR);
6179 private void decodeM(int prefices, int modrm, int sib, int displacement)
6181 if (!decodingAddressMode()) return;
6183 if ((prefices & PREFICES_ADDRESS) != 0) {
6184 //32 bit address size
6186 //Segment load
6187 switch (prefices & PREFICES_SG) {
6188 default:
6189 switch (modrm & 0xc7) {
6190 default: working.write(LOAD_SEG_DS); break;
6191 case 0x04:
6192 case 0x44:
6193 case 0x84: break; //segment working.write will occur in decodeSIB
6194 case 0x45:
6195 case 0x85: working.write(LOAD_SEG_SS); break;
6197 break;
6198 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6199 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6200 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6201 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6202 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6203 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6206 //Address Load
6207 switch(modrm & 0x7) {
6208 case 0x0: working.write(ADDR_EAX); break;
6209 case 0x1: working.write(ADDR_ECX); break;
6210 case 0x2: working.write(ADDR_EDX); break;
6211 case 0x3: working.write(ADDR_EBX); break;
6212 case 0x4: decodeSIB(prefices, modrm, sib, displacement); break;
6213 case 0x5:
6214 if((modrm & 0xc0) == 0x00) {
6215 working.write(ADDR_ID);
6216 working.write(displacement);
6217 } else
6218 working.write(ADDR_EBP);
6219 break;
6220 case 0x6: working.write(ADDR_ESI); break;
6221 case 0x7: working.write(ADDR_EDI); break;
6224 switch(modrm & 0xc0) {
6225 case 0x40: working.write(ADDR_IB); working.write(displacement); break;
6226 case 0x80: working.write(ADDR_ID); working.write(displacement); break;
6228 } else {
6229 //16 bit address size
6230 //Segment load
6231 switch (prefices & PREFICES_SG) {
6232 default:
6233 switch (modrm & 0xc7) {
6234 default: working.write(LOAD_SEG_DS); break;
6235 case 0x02:
6236 case 0x03:
6237 case 0x42:
6238 case 0x43:
6239 case 0x46:
6240 case 0x82:
6241 case 0x83:
6242 case 0x86: working.write(LOAD_SEG_SS); break;
6244 break;
6245 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6246 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6247 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6248 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6249 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6250 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6253 switch (modrm & 0x7) {
6254 case 0x0: working.write(ADDR_BX); working.write(ADDR_SI); break;
6255 case 0x1: working.write(ADDR_BX); working.write(ADDR_DI); break;
6256 case 0x2: working.write(ADDR_BP); working.write(ADDR_SI); break;
6257 case 0x3: working.write(ADDR_BP); working.write(ADDR_DI); break;
6258 case 0x4: working.write(ADDR_SI); break;
6259 case 0x5: working.write(ADDR_DI); break;
6260 case 0x6:
6261 if ((modrm & 0xc0) == 0x00) {
6262 working.write(ADDR_IW);
6263 working.write(displacement);
6264 } else {
6265 working.write(ADDR_BP);
6267 break;
6268 case 0x7: working.write(ADDR_BX); break;
6271 switch (modrm & 0xc0) {
6272 case 0x40: working.write(ADDR_IB); working.write(displacement); break;
6273 case 0x80: working.write(ADDR_IW); working.write(displacement); break;
6275 working.write(ADDR_MASK16);
6279 private void decodeSIB(int prefices, int modrm, int sib, int displacement)
6281 switch (prefices & PREFICES_SG) {
6282 default:
6283 switch (sib & 0x7) {
6284 default: working.write(LOAD_SEG_DS); break;
6285 case 0x4: working.write(LOAD_SEG_SS); break;
6286 case 0x5:
6287 switch (modrm & 0xc0) {
6288 default: working.write(LOAD_SEG_SS); break;
6289 case 0x00: working.write(LOAD_SEG_DS); break;
6290 } break;
6291 } break;
6292 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6293 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6294 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6295 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6296 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6297 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6300 // base register
6301 switch (sib & 0x7) {
6302 case 0x0: working.write(ADDR_EAX); break;
6303 case 0x1: working.write(ADDR_ECX); break;
6304 case 0x2: working.write(ADDR_EDX); break;
6305 case 0x3: working.write(ADDR_EBX); break;
6306 case 0x4: working.write(ADDR_ESP); break;
6307 case 0x5:
6308 switch (modrm & 0xc0) {
6309 default: working.write(ADDR_EBP); break;
6310 case 0x00: working.write(ADDR_ID); working.write(displacement); break;
6311 } break;
6312 case 0x6: working.write(ADDR_ESI); break;
6313 case 0x7: working.write(ADDR_EDI); break;
6316 // index register
6317 switch (sib & 0xf8) {
6318 case 0x00: working.write(ADDR_EAX); break;
6319 case 0x08: working.write(ADDR_ECX); break;
6320 case 0x10: working.write(ADDR_EDX); break;
6321 case 0x18: working.write(ADDR_EBX); break;
6322 case 0x20: break; //none
6323 case 0x28: working.write(ADDR_EBP); break;
6324 case 0x30: working.write(ADDR_ESI); break;
6325 case 0x38: working.write(ADDR_EDI); break;
6327 case 0x40: working.write(ADDR_2EAX); break;
6328 case 0x48: working.write(ADDR_2ECX); break;
6329 case 0x50: working.write(ADDR_2EDX); break;
6330 case 0x58: working.write(ADDR_2EBX); break;
6331 case 0x60: break; //none
6332 case 0x68: working.write(ADDR_2EBP); break;
6333 case 0x70: working.write(ADDR_2ESI); break;
6334 case 0x78: working.write(ADDR_2EDI); break;
6336 case 0x80: working.write(ADDR_4EAX); break;
6337 case 0x88: working.write(ADDR_4ECX); break;
6338 case 0x90: working.write(ADDR_4EDX); break;
6339 case 0x98: working.write(ADDR_4EBX); break;
6340 case 0xa0: break; //none
6341 case 0xa8: working.write(ADDR_4EBP); break;
6342 case 0xb0: working.write(ADDR_4ESI); break;
6343 case 0xb8: working.write(ADDR_4EDI); break;
6345 case 0xc0: working.write(ADDR_8EAX); break;
6346 case 0xc8: working.write(ADDR_8ECX); break;
6347 case 0xd0: working.write(ADDR_8EDX); break;
6348 case 0xd8: working.write(ADDR_8EBX); break;
6349 case 0xe0: break; //none
6350 case 0xe8: working.write(ADDR_8EBP); break;
6351 case 0xf0: working.write(ADDR_8ESI); break;
6352 case 0xf8: working.write(ADDR_8EDI); break;
6356 private void decodeSegmentPrefix(int prefices)
6358 switch (prefices & PREFICES_SG) {
6359 default:
6360 case PREFICES_DS: working.write(LOAD_SEG_DS); break;
6361 case PREFICES_ES: working.write(LOAD_SEG_ES); break;
6362 case PREFICES_SS: working.write(LOAD_SEG_SS); break;
6363 case PREFICES_CS: working.write(LOAD_SEG_CS); break;
6364 case PREFICES_FS: working.write(LOAD_SEG_FS); break;
6365 case PREFICES_GS: working.write(LOAD_SEG_GS); break;
6369 private void store0_Rd(int modrm)
6371 switch (modrm & 0xc7) {
6372 case 0xc0: working.write(STORE0_EAX); break;
6373 case 0xc1: working.write(STORE0_ECX); break;
6374 case 0xc2: working.write(STORE0_EDX); break;
6375 case 0xc3: working.write(STORE0_EBX); break;
6376 case 0xc4: working.write(STORE0_ESP); break;
6377 case 0xc5: working.write(STORE0_EBP); break;
6378 case 0xc6: working.write(STORE0_ESI); break;
6379 case 0xc7: working.write(STORE0_EDI); break;
6380 default: throw new IllegalStateException("Rd cannot be a memory location");
6384 private void load0_Rd(int modrm)
6386 switch (modrm & 0xc7) {
6387 case 0xc0: working.write(LOAD0_EAX); break;
6388 case 0xc1: working.write(LOAD0_ECX); break;
6389 case 0xc2: working.write(LOAD0_EDX); break;
6390 case 0xc3: working.write(LOAD0_EBX); break;
6391 case 0xc4: working.write(LOAD0_ESP); break;
6392 case 0xc5: working.write(LOAD0_EBP); break;
6393 case 0xc6: working.write(LOAD0_ESI); break;
6394 case 0xc7: working.write(LOAD0_EDI); break;
6395 default: throw new IllegalStateException("Rd cannot be a memory location");
6399 private static class Operation
6401 private int[] microcodes;
6402 private int microcodesLength;
6403 private int x86Length;
6404 private int readOffset;
6405 private boolean decoded;
6406 private boolean terminal;
6408 Operation()
6410 microcodes = new int[10];
6413 void write(int microcode)
6415 try {
6416 microcodes[microcodesLength] = microcode;
6417 microcodesLength++;
6418 } catch (ArrayIndexOutOfBoundsException e) {
6419 int[] temp = new int[2*microcodes.length];
6420 System.arraycopy(microcodes, 0, temp, 0, microcodes.length);
6421 microcodes = temp;
6422 microcodes[microcodesLength++] = microcode;
6426 void replace(int offset, int microcode)
6428 microcodes[offset] = microcode;
6431 void finish(int x86Length)
6433 this.x86Length = x86Length;
6434 decoded = true;
6437 void makeTerminal()
6439 reset();
6440 terminal = true;
6443 boolean terminal()
6445 return terminal;
6448 boolean decoded()
6450 return decoded;
6453 void reset()
6455 microcodesLength = 0;
6456 x86Length = 0;
6457 readOffset = 0;
6458 decoded = false;
6459 terminal = false;
6462 int getMicrocodeAt(int offset)
6464 return microcodes[offset];
6467 int getMicrocode()
6469 if (readOffset < microcodesLength)
6470 return microcodes[readOffset++];
6471 else {
6472 System.err.println("Critical error: Attempted to read outside microcode array.");
6473 throw new IllegalStateException("Attempted read outside microcode array");
6477 int getLength()
6479 return microcodesLength;
6482 int getX86Length()
6484 return x86Length;