source: vendor/emx/current/src/dos/disasm.asm

Last change on this file was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 68.9 KB
Line 
1;
2; DISASM.ASM -- Disassembler
3;
4; Copyright (c) 1991-1995 by Eberhard Mattes
5;
6; This file is part of emx.
7;
8; emx is free software; you can redistribute it and/or modify it
9; under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2, or (at your option)
11; any later version.
12;
13; emx is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17;
18; You should have received a copy of the GNU General Public License
19; along with emx; see the file COPYING. If not, write to
20; the Free Software Foundation, 59 Temple Place - Suite 330,
21; Boston, MA 02111-1307, USA.
22;
23; See emx.asm for a special exception.
24;
25
26DISASM_FLAG = 1 ; Include disassembler?
27 ; Not yet implemented
28
29 INCLUDE EMX.INC
30 INCLUDE SYMBOLS.INC
31
32 PUBLIC DISASM
33
34 IF DISASM_FLAG
35
36SV_DATA SEGMENT
37
38SIZE_ON = 01H
39SIZE_OFF = 00H
40
41F_SIGNED = 01H
42F_EMPTY = 02H
43F_NO_PTR = 04H
44
45V_REPE = 1
46V_REPNE = 2
47
48RELOCATION DD ? ; Add this to EIP
49MODE_32 DB ? ; Operand/address size (default)
50PFX_ASIZE DB ? ; Address size prefix
51PFX_OSIZE DB ? ; Operand size prefix
52PFX_SEG DB ? ; Segment override
53PFX_REP DB ? ; Repeat prefix
54PFX_LOCK DB ?
55FLAGS DB ?
56OPCODE DB ?
57OPSIZE DB ?
58MOD_REG_RM DB ?
59SIB DB ?
60ACCU DB ?
61SYM_FLAG DB ?
62SYM_ADDR DD ?
63
64$REG16 DB "AXCXDXBXSPBPSIDI"
65$REG8 DB "ALCLDLBLAHCHDHBH"
66
67$BYTE DB "byte", 0
68$DWORD DB "d"
69$WORD DB "word", 0
70$PTR DB " ptr ",0
71
72 DW 32 DUP (?)
73DISASM_STACK LABEL WORD
74DISASM_SP DW ?
75 DB 16 DUP (?)
76ACCU_STACK LABEL BYTE
77ACCU_SP DW ?
78
79NOT_FLAG DB ?
80
81RM_BX = 01H
82RM_BP = 02H
83RM_SI = 04H
84RM_DI = 08H
85
86RM_TAB DB RM_BX+RM_SI
87 DB RM_BX+RM_DI
88 DB RM_BP+RM_SI
89 DB RM_BP+RM_DI
90 DB RM_SI
91 DB RM_DI
92 DB RM_BP
93 DB RM_BX
94
95DISASM_JMP DW Q_END, Q_DWORD, Q_JUMP, Q_DISP
96 DW Q_NOT, Q_OPCODE, Q_SWITCH, Q_MASK_EQ
97 DW Q_LD_MOD_REG_RM, Q_TEST, Q_BITS, Q_CMP
98 DW Q_REG, Q_REGA, Q_MEM, Q_FLAGS
99 DW Q_NIBBLE, Q_ACCUM, Q_MORE, Q_O16
100 DW Q_A16, Q_BYTE, Q_WORD, Q_TABLE
101 DW Q_RET, Q_PREFIX, Q_EXT, Q_OP_SIZE
102 DW Q_JMP_DST, Q_IMMED, Q_MOD_REG_RM, Q_OP
103
104EXT_JMP DW Q_PUSH, Q_POP, Q_XCHG, Q_BACK
105
106Z_END = 00H
107Z_DWORD = 01H
108Z_JUMP = 02H
109Z_DISP = 03H
110Z_NOT = 04H
111Z_OPCODE = 05H
112Z_SWITCH = 06H
113Z_MASK_EQ = 07H
114Z_LD_MOD_REG_RM = 08H
115Z_TEST = 09H
116Z_BITS = 0AH
117Z_CMP = 0BH
118Z_REG = 0CH
119Z_REGA = 0DH
120Z_MEM = 0EH
121Z_FLAGS = 0FH
122Z_NIBBLE = 10H
123Z_ACCUM = 11H
124Z_MORE = 12H
125Z_O16 = 13H
126Z_A16 = 14H
127Z_BYTE = 15H
128Z_WORD = 16H
129Z_TABLE = 17H
130Z_RET = 18H
131Z_PREFIX = 19H
132Z_EXT = 1AH ; Currently not used
133Z_OP_SIZE = 1BH
134Z_JMP_DST = 1CH
135Z_IMMED = 1DH
136Z_MOD_REG_RM = 1EH
137Z_OP = 1FH
138
139ZE_PUSH = 00H
140ZE_POP = 01H
141ZE_XCHG = 02H
142ZE_BACK = 03H
143
144; ============================================================================
145; Disassembler language
146; ============================================================================
147
148;
149; Utility macros (required for expansion of numeric variables (N)
150;
151VSET MACRO V, N, X
152V&N = X
153 ENDM
154VINC MACRO V, N
155V&N = V&N + 1
156 ENDM
157VDB MACRO V, N
158 DB V&N
159 ENDM
160VDW MACRO V, N
161 DW V&N
162 ENDM
163
164;
165; End of program
166;
167X_END MACRO
168 DB Z_END
169 ENDM
170
171;
172; Fetch DWORD from input and insert into output
173;
174X_DWORD MACRO
175 DB Z_DWORD
176 ENDM
177
178;
179; Jump to another location
180;
181X_JUMP MACRO DST
182 DB Z_JUMP
183 DW DST
184 ENDM
185
186;
187; Call subroutine (note: no checking for stack overflow)
188;
189X_CALL MACRO DST
190 DB CALL_&DST
191 ENDM
192;
193; Define subroutine
194;
195CALLCNT = 0
196X_SUB MACRO NAME
197CALL_&NAME = 80H + CALLCNT
198 VSET CALLV,%CALLCNT, <THIS BYTE>
199CALLCNT = CALLCNT + 1
200 ENDM
201;
202; Negate condition of next conditional jump instruction
203;
204X_NOT MACRO
205 DB Z_NOT
206 ENDM
207
208;
209; X_OPCODE
210;
211; Reload opcode into accu
212;
213X_OPCODE MACRO
214 DB Z_OPCODE
215 ENDM
216
217
218SWCNT = 0
219
220;
221; Switch statement (accu)
222;
223X_SWITCH MACRO
224SWCNT = SWCNT+1
225 DB Z_SWITCH
226 VDB SWLEN, %SWCNT
227 VSET SWLEN, %SWCNT, 0
228 ENDM
229
230;
231; One case of a switch statement: jump to DST, if accu==VALUE
232;
233X_CASE MACRO VALUE, DST
234 VINC SWLEN, %SWCNT
235 DB VALUE
236 DW DST
237 ENDM
238
239;
240; Jump to DST, if (accu & MASK) == VALUE
241;
242X_MASK_EQ MACRO MASK, VALUE, DST
243 DB Z_MASK_EQ, MASK, VALUE
244 DW DST
245 ENDM
246
247;
248; Load accu from mod,reg,r/m byte
249;
250X_LD_MOD_REG_RM MACRO
251 DB Z_LD_MOD_REG_RM
252 ENDM
253
254;
255; Load accu from reg field of mod,reg,r/m byte
256;
257X_LOAD_REG MACRO
258 X_CALL P_LOAD_REG
259 ENDM
260
261;
262; Jump to DST, if (accu & MASK) != 0
263;
264; (If we run out of instruction codes, this can be done with Z_MASK_EQ.)
265;
266X_TEST MACRO MASK, DST
267 DB Z_TEST, MASK
268 DW DST
269 ENDM
270
271;
272; Extract a bit field of accu: accu := (accu AND MASK) SHR b,
273; with b = min {i | (MASK AND (1 SHL i)) != 0}
274;
275; Example:
276; accu = 01101101
277; MASK = 00111000
278; result = 00000101 (bits 3..5 of accu moved to bits 0..2)
279;
280X_BITS MACRO MASK
281 DB Z_BITS, MASK
282 ENDM
283
284;
285; Jump to DST, if variable SRC contains VALUE
286;
287X_CMP MACRO SRC, VALUE, DST
288 DB Z_CMP
289 DW SRC
290 DB VALUE
291 DW DST
292 ENDM
293
294;
295; Insert name of register specified by reg field of reg,mod,r/m byte
296;
297X_REG MACRO
298 DB Z_REG
299 ENDM
300
301;
302; Insert name of register specified by bits 0..2 of accu
303;
304X_REGA MACRO
305 DB Z_REGA
306 ENDM
307
308;
309; Insert operand specified by mod & r/m fields of reg,mod,r/m byte
310;
311X_MEM MACRO
312 DB Z_MEM
313 ENDM
314
315;
316; Insert destination address of a short jump instruction
317;
318X_SHORT MACRO
319 DB Z_JMP_DST, 0
320 ENDM
321
322;
323; Insert destination address of a near jump instruction
324;
325X_NEAR MACRO
326 DB Z_JMP_DST, 1
327 ENDM
328
329;
330; Insert destination address of a far jump instruction
331;
332X_FAR MACRO
333 DB Z_JMP_DST, 2
334 ENDM
335
336;
337; Insert name of 8/16/32 bit accumulator (AL/AX/EAX)
338;
339X_ACCUM MACRO
340 DB Z_ACCUM
341 ENDM
342
343;
344; Jump to DST, if operand size = 16 bit
345;
346X_O16 MACRO DST
347 DB Z_O16
348 DW DST
349 ENDM
350
351;
352; Jump to DST, if address size = 16 bit
353;
354X_A16 MACRO DST
355 DB Z_A16
356 DW DST
357 ENDM
358
359;
360; Fetch mod,reg,r/m byte
361;
362X_MOD_REG_RM MACRO
363 DB Z_MOD_REG_RM
364 ENDM
365
366;
367; Insert opcode / operand delimiter into output
368;
369X_OP MACRO
370 DB Z_OP
371 ENDM
372
373;
374; Fetch BYTE from input and insert into output
375;
376X_BYTE MACRO
377 DB Z_BYTE
378 ENDM
379
380;
381; Fetch WORD from input and insert into output
382;
383X_WORD MACRO
384 DB Z_WORD
385 ENDM
386
387;
388; Insert [xxxx] (WORD/DWORD, depending on address size)
389;
390X_DISP MACRO
391 DB Z_DISP
392 ENDM
393
394;
395; Table jump: load accu'th (0..255) word following this instruction
396; into instruction pointer
397; Attention: be sure that there's a table entry for all possible values
398; of accu!
399;
400X_TABLE MACRO
401 DB Z_TABLE
402 ENDM
403
404;
405; Return from subroutine
406;
407X_RET MACRO
408 DB Z_RET
409 ENDM
410
411;
412; Handle prefix instruction: store VALUE to variable PREFIX,
413; fetch next opcode byte, and restart program
414;
415X_PREFIX MACRO PREFIX, VALUE
416 DB Z_PREFIX
417 DW PREFIX
418 DB VALUE
419 ENDM
420
421;
422; Insert operand / operand delimiter into output
423;
424X_COMMA MACRO
425 X_CALL P_COMMA
426 ENDM
427
428;
429; Switch operand size to BYTE (note 1)
430;
431X_BYTE_OP MACRO
432 DB Z_OP_SIZE, 00H
433 ENDM
434
435;
436; Switch operand size to WORD (note 1)
437;
438X_WORD_OP MACRO
439 DB Z_OP_SIZE, 01H
440 ENDM
441
442;
443; Switch operand size to FWORD (note 1)
444;
445X_FAR_OP MACRO
446 DB Z_OP_SIZE, 02H
447 ENDM
448
449;
450; Insert immediate operand into output (uses F_SIGNED flag)
451;
452X_IMMED MACRO
453 DB Z_IMMED
454 ENDM
455
456;
457; Fetch next opcode byte
458;
459X_MORE MACRO
460 DB Z_MORE
461 ENDM
462
463;
464; Set F_SIGNED flag (for immediate operands)
465;
466X_SIGNED MACRO
467 DB Z_FLAGS, F_SIGNED
468 ENDM
469
470;
471; Set F_EMPTY flag (after JMP/RET/... instructions)
472;
473X_EMPTY MACRO
474 DB Z_FLAGS, F_EMPTY
475 ENDM
476
477;
478; Set F_NO_PTR flag (omit `byte ptr' etc.)
479;
480X_NO_PTR MACRO
481 DB Z_FLAGS, F_NO_PTR
482 ENDM
483
484;
485; Insert accu into output (bits 0..3 in hexadecimal representation)
486;
487X_NIBBLE MACRO
488 DB Z_NIBBLE
489 ENDM
490
491;
492; Push accu on stack
493;
494X_PUSH MACRO
495 DB Z_EXT, ZE_PUSH
496 ENDM
497
498
499;
500; Pop accu from stack
501;
502X_POP MACRO
503 DB Z_EXT, ZE_POP
504 ENDM
505
506
507;
508; Exchange accu with top of stack
509;
510X_XCHG MACRO
511 DB Z_EXT, ZE_XCHG
512 ENDM
513
514
515;
516; Backup one byte
517;
518X_BACK MACRO
519 DB Z_EXT, ZE_BACK
520 ENDM
521
522
523;
524; Note 1: The default operand size is determined by bit 0 (w) of the
525; current opcode byte.
526;
527
528; ============================================================================
529; This is the 80386 disassembler, written in disassembler language
530; ============================================================================
531;
532; If I had time, I would create a compiler which translates a C like
533; language to this object code. Example:
534;
535; if (op & 0xf8 == 0x50)
536; {
537; "PUSH\t"; word_op; reg_a; end;
538; }
539;
540; But of course I don't have time. Therefore, this disassembler is
541; somewhat cryptic.
542;
543;
544DISASM_PROGRAM LABEL BYTE
545 X_SWITCH
546 X_CASE 0FH, P_0F
547 X_CASE 26H, P_ES
548 X_CASE 27H, P_DAA
549 X_CASE 2EH, P_CS
550 X_CASE 2FH, P_DAS
551 X_CASE 36H, P_SS
552 X_CASE 37H, P_AAA
553 X_CASE 3EH, P_DS
554 X_CASE 3FH, P_AAS
555 X_CASE 60H, P_PUSHA
556 X_CASE 61H, P_POPA
557 X_CASE 62H, P_BOUND
558 X_CASE 63H, P_ARPL
559 X_CASE 64H, P_FS
560 X_CASE 65H, P_GS
561 X_CASE 66H, P_O_PFX
562 X_CASE 67H, P_A_PFX
563 X_CASE 8DH, P_LEA
564 X_CASE 8FH, P_POP_MEM
565 X_CASE 90H, P_NOP
566 X_CASE 98H, P_CBW
567 X_CASE 99H, P_CDQ
568 X_CASE 9AH, P_CALLF
569 X_CASE 9BH, P_WAIT
570 X_CASE 9CH, P_PUSHF
571 X_CASE 9DH, P_POPF
572 X_CASE 9EH, P_SAHF
573 X_CASE 9FH, P_LAHF
574 X_CASE 0C4H, P_LES
575 X_CASE 0C5H, P_LDS
576 X_CASE 0C8H, P_ENTER
577 X_CASE 0C9H, P_LEAVE
578 X_CASE 0CCH, P_INT3
579 X_CASE 0CDH, P_INT
580 X_CASE 0CEH, P_INTO
581 X_CASE 0CFH, P_IRET
582 X_CASE 0D4H, P_AAM
583 X_CASE 0D5H, P_AAD
584 X_CASE 0D7H, P_XLAT
585 X_CASE 0E0H, P_LOOPNE
586 X_CASE 0E1H, P_LOOPE
587 X_CASE 0E2H, P_LOOP
588 X_CASE 0E3H, P_JCXZ
589 X_CASE 0E8H, P_CALLN
590 X_CASE 0E9H, P_JMPN
591 X_CASE 0EAH, P_JMPF
592 X_CASE 0EBH, P_JMPS
593 X_CASE 0F0H, P_LOCK
594 X_CASE 0F2H, P_REPNE
595 X_CASE 0F3H, P_REPE
596 X_CASE 0F4H, P_HLT
597 X_CASE 0F5H, P_CMC
598 X_CASE 0F8H, P_CLC
599 X_CASE 0F9H, P_STC
600 X_CASE 0FAH, P_CLI
601 X_CASE 0FBH, P_STI
602 X_CASE 0FCH, P_CLD
603 X_CASE 0FDH, P_STD
604 X_MASK_EQ 0F0H, 70H, P_JCOND8
605 X_MASK_EQ 0F8H, 50H, P_PUSH
606 X_MASK_EQ 0F8H, 58H, P_POP
607 X_MASK_EQ 0F8H, 40H, P_INC2
608 X_MASK_EQ 0F8H, 48H, P_DEC2
609 X_MASK_EQ 0F8H, 90H, P_XCHG2
610 X_MASK_EQ 0F8H, 0B0H, P_MOV3B
611 X_MASK_EQ 0F8H, 0B8H, P_MOV3W
612 X_MASK_EQ 0F8H, 0D8H, P_ESC
613 X_MASK_EQ 0FCH, 80H, P_ARITH2
614 X_MASK_EQ 0FCH, 88H, P_MOV1
615 X_MASK_EQ 0FCH, 0A0H, P_MOV4
616 X_MASK_EQ 0FDH, 68H, P_PUSH_IMMED
617 X_MASK_EQ 0FDH, 69H, P_IMUL_IMMED
618 X_MASK_EQ 0FDH, 8CH, P_MOV5
619 X_MASK_EQ 0FEH, 6CH, P_INS
620 X_MASK_EQ 0FEH, 6EH, P_OUTS
621 X_MASK_EQ 0FEH, 84H, P_TEST1
622 X_MASK_EQ 0FEH, 86H, P_XCHG1
623 X_MASK_EQ 0FEH, 0A4H, P_MOVS
624 X_MASK_EQ 0FEH, 0A6H, P_CMPS
625 X_MASK_EQ 0FEH, 0A8H, P_TEST3
626 X_MASK_EQ 0FEH, 0AAH, P_STOS
627 X_MASK_EQ 0FEH, 0ACH, P_LODS
628 X_MASK_EQ 0FEH, 0AEH, P_SCAS
629 X_MASK_EQ 0FEH, 0C0H, P_ROTATE3
630 X_MASK_EQ 0FEH, 0C2H, P_RETN
631 X_MASK_EQ 0FEH, 0CAH, P_RETF
632 X_MASK_EQ 0FEH, 0C6H, P_MOV2
633 X_MASK_EQ 0FEH, 0D0H, P_ROTATE1
634 X_MASK_EQ 0FEH, 0D2H, P_ROTATE2
635 X_MASK_EQ 0FEH, 0E4H, P_IN1
636 X_MASK_EQ 0FEH, 0E6H, P_OUT1
637 X_MASK_EQ 0FEH, 0ECH, P_IN2
638 X_MASK_EQ 0FEH, 0EEH, P_OUT2
639 X_MASK_EQ 0FEH, 0F6H, P_F6_F7
640 X_MASK_EQ 0FEH, 0FEH, P_FE_FF
641 X_MASK_EQ 0E7H, 07H, P_POP_SEG
642 X_MASK_EQ 0C4H, 00H, P_ARITH1
643 X_MASK_EQ 0C6H, 04H, P_ARITH3
644 X_MASK_EQ 0C7H, 06H, P_PUSH_SEG
645FAILURE DB "???", Z_END
646
647P_0F LABEL BYTE
648 X_MORE
649 X_SWITCH
650 X_CASE 00H, P_0F00
651 X_CASE 01H, P_0F01
652 X_CASE 02H, P_LAR
653 X_CASE 03H, P_LSL
654 X_CASE 06H, P_CLTS
655 X_CASE 20H, P_MOV_FROM_CR
656 X_CASE 21H, P_MOV_FROM_DR
657 X_CASE 22H, P_MOV_TO_CR
658 X_CASE 23H, P_MOV_TO_DR
659 X_CASE 24H, P_MOV_FROM_TR
660 X_CASE 26H, P_MOV_TO_TR
661 X_CASE 0A4H, P_SHLD_IMMED
662 X_CASE 0A5H, P_SHLD_CL
663 X_CASE 0ACH, P_SHRD_IMMED
664 X_CASE 0ADH, P_SHRD_CL
665 X_CASE 0AFH, P_IMUL_MEM
666 X_CASE 0B2H, P_LSS
667 X_CASE 0B4H, P_LFS
668 X_CASE 0B5H, P_LGS
669 X_CASE 0BAH, P_BT1
670 X_CASE 0BCH, P_BSF
671 X_CASE 0BDH, P_BSR
672 X_MASK_EQ 0FEH, 0BEH, P_MOVSX
673 X_MASK_EQ 0FEH, 0B6H, P_MOVZX
674 X_MASK_EQ 0F0H, 80H, P_JCOND16
675 X_MASK_EQ 0F0H, 90H, P_SET
676 X_MASK_EQ 0E7H, 0A3H, P_BT2
677 X_MASK_EQ 0C7H, 80H, P_PUSH_SEG
678 X_MASK_EQ 0C7H, 81H, P_POP_SEG
679 X_JUMP FAILURE
680
681P_0F00 LABEL BYTE
682 X_MOD_REG_RM
683 X_LOAD_REG
684 X_SWITCH
685 X_CASE 00H, P_SLDT
686 X_CASE 01H, P_STR
687 X_CASE 02H, P_LLDT
688 X_CASE 03H, P_LTR
689 X_CASE 04H, P_VERR
690 X_CASE 05H, P_VERW
691 X_JUMP FAILURE
692
693P_0F01 LABEL BYTE
694 X_MOD_REG_RM
695 X_LOAD_REG
696 X_SWITCH
697 X_CASE 00H, P_SGDT
698 X_CASE 01H, P_SIDT
699 X_CASE 02H, P_LGDT
700 X_CASE 03H, P_LIDT
701 X_CASE 04H, P_SMSW
702 X_CASE 06H, P_LMSW
703 X_JUMP FAILURE
704
705P_FE_FF LABEL BYTE
706 X_MOD_REG_RM
707 X_LOAD_REG
708 X_SWITCH
709 X_CASE 00H, P_INC1
710 X_CASE 01H, P_DEC1
711 X_CASE 02H, P_CALL_INDN
712 X_CASE 03H, P_CALL_INDF
713 X_CASE 04H, P_JMP_INDN
714 X_CASE 05H, P_JMP_INDF
715 X_CASE 06H, P_PUSH_MEM
716 X_JUMP FAILURE
717
718P_F6_F7 LABEL BYTE
719 X_MOD_REG_RM
720 X_LOAD_REG
721 X_SWITCH
722 X_CASE 00H, P_TEST2
723 X_CASE 02H, P_NOT
724 X_CASE 03H, P_NEG
725 X_CASE 04H, P_MUL
726 X_CASE 05H, P_IMUL
727 X_CASE 06H, P_DIV
728 X_CASE 07H, P_IDIV
729 X_JUMP FAILURE
730
731P_AAA DB "AAA", Z_END
732P_AAS DB "AAS", Z_END
733P_DAA DB "DAA", Z_END
734P_DAS DB "DAS", Z_END
735P_HLT DB "HLT", Z_END
736P_NOP DB "NOP", Z_END
737P_CMC DB "CMC", Z_END
738P_CLC DB "CLC", Z_END
739P_CLI DB "CLI", Z_END
740P_CLD DB "CLD", Z_END
741P_STC DB "STC", Z_END
742P_STI DB "STI", Z_END
743P_STD DB "STD", Z_END
744P_CLTS DB "CLTS", Z_END
745P_INTO DB "INTO", Z_END
746P_LAHF DB "LAHF", Z_END
747P_SAHF DB "SAHF", Z_END
748P_LEAVE DB "LEAVE", Z_END
749P_WAIT DB "WAIT", Z_END
750
751;
752; XLAT
753;
754; Bug: prefix ignored
755;
756P_XLAT DB "XLAT", Z_END
757
758P_A_PFX LABEL BYTE
759 X_PREFIX PFX_ASIZE, SIZE_ON
760
761P_O_PFX LABEL BYTE
762 X_PREFIX PFX_OSIZE, SIZE_ON
763
764P_CS LABEL BYTE
765 X_PREFIX PFX_SEG, "C"
766
767P_DS LABEL BYTE
768 X_PREFIX PFX_SEG, "D"
769
770P_ES LABEL BYTE
771 X_PREFIX PFX_SEG, "E"
772
773P_FS LABEL BYTE
774 X_PREFIX PFX_SEG, "F"
775
776P_GS LABEL BYTE
777 X_PREFIX PFX_SEG, "G"
778
779P_SS LABEL BYTE
780 X_PREFIX PFX_SEG, "S"
781
782P_LOCK DB "LOCK "
783 X_PREFIX PFX_LOCK, 1
784
785P_REPE LABEL BYTE
786 X_PREFIX PFX_REP, V_REPE
787
788P_REPNE LABEL BYTE
789 X_PREFIX PFX_REP, V_REPNE
790
791P_AAM DB "AAM"
792 X_JUMP P_10
793P_AAD DB "AAD"
794P_10 LABEL BYTE
795 X_MORE
796 X_CMP OPCODE, 10, P_10_1
797 DB Z_OP, Z_BYTE
798P_10_1 DB Z_END
799
800
801P_INT DB "INT", Z_OP, Z_BYTE, Z_END
802
803P_INT3 DB "INT", Z_OP, "3", Z_END
804
805P_ENTER DB "ENTER", Z_OP
806 X_WORD
807 X_COMMA
808 X_BYTE
809 X_END
810
811P_LSS DB "LS"
812 X_JUMP P_LSEG
813
814P_LFS DB "LF"
815 X_JUMP P_LSEG
816
817P_LGS DB "LG"
818 X_JUMP P_LSEG
819
820P_LES DB "LE"
821 X_JUMP P_LSEG
822
823P_LDS DB "LD"
824P_LSEG DB "S"
825 X_FAR_OP
826 X_CALL OP_REG_MEM ; (OP) reg, mem (END)
827
828P_PUSH LABEL BYTE
829 X_CALL TPUSH
830 X_JUMP P_PUSH_POP
831
832P_POP LABEL BYTE
833 X_CALL TPOP
834P_PUSH_POP LABEL BYTE
835 X_WORD_OP
836 DB Z_REGA, Z_END
837
838P_PUSHF DB "PUSHF"
839 X_CALL APPEND_D
840
841P_POPF DB "POPF"
842 X_CALL APPEND_D
843
844P_PUSHA DB "PUSHA"
845 X_CALL APPEND_D
846
847P_POPA DB "POPA"
848 X_CALL APPEND_D
849
850P_IRET DB "IRET"
851 X_EMPTY
852 X_CALL APPEND_D
853
854P_CBW DB "C"
855 X_O16 P_CBW_1
856 DB "WDE", Z_END
857P_CBW_1 DB "BW", Z_END
858
859P_CDQ DB "C"
860 X_O16 P_CDQ_1
861 DB "DQ", Z_END
862P_CDQ_1 DB "WD", Z_END
863
864
865P_LTR DB "LTR"
866 X_CALL WMEM
867
868P_STR DB "STR"
869 X_CALL WMEM
870
871P_LLDT DB "LLDT"
872 X_CALL WMEM
873
874P_LGDT DB "LGDT"
875 X_CALL WMEM ; bug: should be FWORD PTR
876
877P_LIDT DB "LIDT"
878 X_CALL WMEM ; bug: should be FWORD PTR
879
880P_VERR DB "VERR"
881 X_CALL WMEM
882
883P_VERW DB "VERW"
884 X_CALL WMEM
885
886P_SLDT DB "SLDT"
887 X_CALL WMEM
888
889P_SGDT DB "SGDT"
890 X_CALL WMEM ; bug: should be FWORD PTR
891
892P_SIDT DB "SIDT"
893 X_CALL WMEM ; bug: should be FWORD PTR
894
895P_LAR DB "LAR"
896P_LAR_1 LABEL BYTE
897 X_WORD_OP
898 X_CALL OP_REG_MEM ; (OP) reg, mem (END)
899
900P_LSL DB "LSL"
901 X_JUMP P_LAR_1
902
903P_LMSW DB "LMSW"
904 X_CALL WMEM
905
906P_SMSW DB "SMSW"
907 X_CALL WMEM
908
909;
910; Bug in 16 bit mode: reg16 instead of reg32
911;
912P_MOV_TO_CR LABEL BYTE
913 X_CALL TMOV
914 DB "C"
915 X_JUMP MOV_TO_SPEC
916
917P_MOV_FROM_CR LABEL BYTE
918 X_CALL TMOV
919 DB Z_MOD_REG_RM
920 X_WORD_OP
921 X_MEM
922 X_COMMA
923 DB "C"
924 X_CALL SPECIAL
925 X_END
926
927P_MOV_TO_DR LABEL BYTE
928 X_CALL TMOV
929 DB "D"
930 X_JUMP MOV_TO_SPEC
931
932P_MOV_FROM_DR LABEL BYTE
933 X_CALL TMOV
934 DB Z_MOD_REG_RM
935 X_WORD_OP
936 X_MEM
937 X_COMMA
938 DB "D"
939 X_CALL SPECIAL
940 X_END
941
942P_MOV_TO_TR LABEL BYTE
943 X_CALL TMOV
944 DB "T"
945MOV_TO_SPEC LABEL BYTE
946 X_MOD_REG_RM
947 X_WORD_OP
948 X_CALL SPECIAL
949 X_COMMA
950 DB Z_MEM, Z_END
951
952P_MOV_FROM_TR LABEL BYTE
953 X_CALL TMOV
954 DB Z_MOD_REG_RM
955 X_WORD_OP
956 X_MEM
957 X_COMMA
958 DB "T"
959 X_CALL SPECIAL
960 X_END
961
962P_SHLD_IMMED LABEL BYTE
963 X_CALL TSHL
964 X_JUMP P_SHD_IMMED
965P_SHRD_IMMED LABEL BYTE
966 X_CALL TSHR
967P_SHD_IMMED DB "D", Z_OP, Z_MOD_REG_RM
968 X_WORD_OP
969 X_MEM
970 X_COMMA
971 X_REG
972 X_COMMA
973 DB Z_BYTE, Z_END
974
975P_SHLD_CL LABEL BYTE
976 X_CALL TSHL
977 X_JUMP P_SHD_CL
978P_SHRD_CL LABEL BYTE
979 X_CALL TSHR
980P_SHD_CL DB "D", Z_OP, Z_MOD_REG_RM
981 X_WORD_OP
982 X_MEM
983 X_COMMA
984 X_REG
985 X_COMMA
986 DB "CL", Z_END
987
988
989;
990; Bug: source operand is 32 bit instead of 16 bit. 8 bit is ok
991;
992P_MOVSX DB "MOVS"
993P_MOVSZ DB "X", Z_OP
994 X_WORD_OP
995 DB Z_MOD_REG_RM, Z_REG
996 X_COMMA
997 X_TEST 01H, P_MOVSZ_1
998 X_BYTE_OP
999P_MOVSZ_1 DB Z_MEM, Z_END
1000
1001P_MOVZX DB "MOVZ"
1002 X_JUMP P_MOVSZ
1003
1004;
1005; bug: address size prefix & segment overide prefix ignored
1006;
1007P_CMPS LABEL BYTE
1008 X_CALL REP_COND
1009 DB "CMPS"
1010STRING_BW LABEL BYTE
1011 X_TEST 01H, STRING_W
1012 DB "B", Z_END
1013STRING_W LABEL BYTE
1014 X_O16 STRING_W1
1015 DB "D", Z_END
1016STRING_W1 DB "W", Z_END
1017
1018
1019 X_SUB REP_COND
1020 X_CMP PFX_REP, 0, REP_COND_2
1021 DB "REP"
1022 X_CMP PFX_REP, V_REPE, REP_COND_1
1023 DB "N"
1024REP_COND_1 DB "E "
1025REP_COND_2 DB Z_RET
1026
1027 X_SUB REP_UNCOND
1028 X_CMP PFX_REP, 0, REP_UNCOND_1
1029 DB "REP "
1030REP_UNCOND_1 DB Z_RET
1031
1032
1033
1034;
1035; bug: address size prefix & segment overide prefix ignored
1036;
1037P_LODS LABEL BYTE
1038 X_CALL REP_UNCOND
1039 DB "LODS"
1040 X_JUMP STRING_BW
1041
1042
1043;
1044; bug: address size prefix & segment overide prefix ignored
1045;
1046P_MOVS LABEL BYTE
1047 X_CALL REP_UNCOND
1048 DB "MOVS"
1049 X_JUMP STRING_BW
1050
1051;
1052; bug: address size prefix & segment overide prefix ignored
1053;
1054P_SCAS LABEL BYTE
1055 X_CALL REP_COND
1056 DB "SCAS"
1057 X_JUMP STRING_BW
1058
1059;
1060; bug: address size prefix & segment overide prefix ignored
1061;
1062P_STOS LABEL BYTE
1063 X_CALL REP_UNCOND
1064 DB "STOS"
1065 X_JUMP STRING_BW
1066
1067;
1068; bug: address size prefix & segment overide prefix ignored
1069;
1070P_INS LABEL BYTE
1071 X_CALL REP_UNCOND
1072 DB "INS"
1073 X_JUMP STRING_BW
1074
1075;
1076; bug: address size prefix & segment overide prefix ignored
1077;
1078P_OUTS LABEL BYTE
1079 X_CALL REP_UNCOND
1080 DB "OUTS"
1081 X_JUMP STRING_BW
1082
1083
1084P_ARPL DB "ARPL"
1085 DB Z_OP, Z_MOD_REG_RM, Z_MEM
1086 X_COMMA
1087 DB Z_REG, Z_END
1088
1089P_BOUND DB "BOUND"
1090 X_CALL OP_REG_MEM ; (OP) reg, mem (END)
1091
1092 X_SUB TPUSH
1093 DB "PUSH", Z_OP, Z_RET
1094
1095 X_SUB TPOP
1096 DB "POP", Z_OP, Z_RET
1097
1098P_PUSH_SEG LABEL BYTE
1099 X_CALL TPUSH
1100 X_BITS 38H
1101 X_CALL SREG
1102 X_END
1103
1104P_PUSH_MEM LABEL BYTE
1105 X_CALL TPUSH
1106 DB Z_MEM, Z_END
1107
1108P_PUSH_IMMED LABEL BYTE
1109 X_CALL TPUSH
1110 X_WORD_OP
1111 X_NOT
1112 X_TEST 02H, P_PUSH_IMMED_1
1113 X_SIGNED
1114P_PUSH_IMMED_1 DB Z_IMMED, Z_END
1115
1116P_POP_SEG LABEL BYTE
1117 X_CALL TPOP
1118 X_BITS 38H
1119 X_CALL SREG
1120 X_END
1121
1122P_POP_MEM LABEL BYTE
1123 X_CALL TPOP
1124 DB Z_MOD_REG_RM, Z_MEM, Z_END
1125
1126
1127P_JMPS LABEL BYTE
1128 X_CALL TJMP
1129 X_SHORT
1130 X_END
1131
1132P_JMPN LABEL BYTE
1133 X_CALL TJMP
1134 X_NEAR
1135 X_END
1136
1137P_JMPF LABEL BYTE
1138 X_CALL TJMP
1139 X_FAR
1140 X_END
1141
1142P_CALLN LABEL BYTE
1143 X_CALL TCALL
1144 X_NEAR
1145 X_END
1146
1147P_CALLF LABEL BYTE
1148 X_CALL TCALL
1149 X_FAR
1150 X_END
1151
1152P_JCXZ DB "J"
1153 X_O16 P_JCXZ1
1154 DB "E"
1155P_JCXZ1 DB "CXZ", Z_OP
1156 X_SHORT
1157 X_END
1158
1159P_LOOP LABEL BYTE
1160 X_CALL TLOOP
1161 X_OP
1162 X_SHORT
1163 X_END
1164
1165P_LOOPE LABEL BYTE
1166 X_CALL TLOOP
1167 DB "E", Z_OP
1168 X_SHORT
1169 X_END
1170
1171P_LOOPNE LABEL BYTE
1172 X_CALL TLOOP
1173 DB "NE", Z_OP
1174 X_SHORT
1175 X_END
1176
1177 X_SUB TLOOP
1178 DB "LOOP", Z_RET
1179
1180P_SET DB "SET"
1181 X_CALL COND
1182 X_BYTE_OP
1183 DB Z_OP, Z_MOD_REG_RM, Z_MEM, Z_END
1184
1185P_JCOND8 DB "J"
1186 X_CALL COND
1187 X_OP
1188 X_SHORT
1189 X_END
1190
1191P_JCOND16 DB "J"
1192 X_CALL COND
1193 DB Z_OP
1194 X_NEAR
1195 X_END
1196
1197P_JMP_INDN LABEL BYTE
1198 X_CALL TJMP
1199P_INDN LABEL BYTE
1200 X_WORD_OP
1201 DB Z_MEM, Z_END
1202
1203P_JMP_INDF LABEL BYTE
1204 X_CALL TJMP
1205P_INDF LABEL BYTE
1206 X_FAR_OP
1207 DB Z_MEM, Z_END
1208
1209P_CALL_INDN LABEL BYTE
1210 X_CALL TCALL
1211 X_JUMP P_INDN
1212
1213P_CALL_INDF LABEL BYTE
1214 X_CALL TCALL
1215 X_JUMP P_INDF
1216
1217 X_SUB TCALL
1218 DB "CALL", Z_OP, Z_RET
1219
1220 X_SUB TJMP
1221 X_EMPTY
1222 DB "JMP", Z_OP, Z_RET
1223
1224 X_SUB TMOV
1225 DB "MOV", Z_OP, Z_RET
1226
1227P_IN1 DB "IN", Z_OP, Z_ACCUM
1228 X_COMMA
1229 DB Z_BYTE, Z_END
1230
1231P_IN2 DB "IN", Z_OP, Z_ACCUM
1232 X_COMMA
1233 DB "DX", Z_END
1234
1235P_OUT1 DB "OUT", Z_OP, Z_BYTE
1236 X_COMMA
1237 DB Z_ACCUM, Z_END
1238
1239P_OUT2 DB "OUT", Z_OP, "DX"
1240 X_COMMA
1241 DB Z_ACCUM, Z_END
1242
1243P_INC1 DB "INC"
1244 X_CALL OP_MEM
1245
1246P_DEC1 DB "DEC"
1247 X_CALL OP_MEM
1248P_INC2 DB "INC", Z_OP
1249 X_WORD_OP
1250 DB Z_REGA, Z_END
1251
1252P_DEC2 DB "DEC", Z_OP
1253 X_WORD_OP
1254 DB Z_REGA, Z_END
1255
1256P_BSF DB "BSF"
1257 X_JUMP P_BS_1
1258P_BSR DB "BSR"
1259P_BS_1 LABEL BYTE
1260 X_WORD_OP
1261 X_CALL OP_REG_MEM ; (OP) reg, mem (END)
1262
1263P_BT1 DB Z_MOD_REG_RM
1264 X_LOAD_REG
1265 X_CALL BIT_TESTS
1266 X_OP
1267 X_MEM
1268 X_COMMA
1269 DB Z_BYTE, Z_END
1270
1271P_BT2 DB Z_MOD_REG_RM
1272 X_BITS 38H
1273 X_CALL BIT_TESTS
1274 X_OP
1275 X_MEM
1276 X_COMMA
1277 DB Z_REG, Z_END
1278
1279 X_SUB BIT_TESTS
1280 DB "BT"
1281 X_BITS 03H
1282 X_TABLE
1283 DW BT00, BT01, BT02, BT03
1284BT00 DB Z_RET
1285BT01 DB "S", Z_RET
1286BT02 DB "R", Z_RET
1287BT03 DB "C", Z_RET
1288
1289
1290P_ROTATE1 DB Z_MOD_REG_RM
1291 X_CALL ROTATE
1292 DB Z_OP, Z_MEM
1293 X_COMMA
1294 DB "1", Z_END
1295
1296P_ROTATE2 DB Z_MOD_REG_RM
1297 X_CALL ROTATE
1298 DB Z_OP, Z_MEM
1299 X_COMMA
1300 DB "CL", Z_END
1301
1302P_ROTATE3 DB Z_MOD_REG_RM
1303 X_CALL ROTATE
1304 DB Z_OP, Z_MEM
1305 X_COMMA
1306 DB Z_BYTE, Z_END
1307
1308
1309 X_SUB ROTATE
1310 X_LOAD_REG
1311 X_TABLE
1312 DW ROTATE00, ROTATE01, ROTATE02, ROTATE03
1313 DW ROTATE04, ROTATE05, ROTATE06, ROTATE07
1314
1315ROTATE00 DB "ROL", Z_RET
1316ROTATE01 DB "ROR", Z_RET
1317ROTATE02 DB "RCL", Z_RET
1318ROTATE03 DB "RCR", Z_RET
1319 X_SUB TSHL
1320ROTATE04 DB "SHL", Z_RET
1321 X_SUB TSHR
1322ROTATE05 DB "SHR", Z_RET
1323ROTATE06 DB "???", Z_RET
1324ROTATE07 DB "SAR", Z_RET
1325
1326 X_SUB TTEST
1327 DB "TEST", Z_OP, Z_RET
1328
1329;
1330; TEST
1331; reg, reg
1332; reg, mem
1333;
1334P_TEST1 LABEL BYTE
1335 X_CALL TTEST
1336 X_CALL REG_MEM ; reg, mem (END)
1337
1338;
1339; Does not return!
1340;
1341; (OP) reg, mem (END)
1342;
1343 X_SUB OP_REG_MEM
1344 X_OP
1345;
1346; reg, mem (END)
1347;
1348 X_SUB REG_MEM
1349 DB Z_MOD_REG_RM, Z_REG
1350 X_COMMA
1351 DB Z_MEM, Z_END
1352
1353
1354
1355;
1356; (OP) mem.w (END)
1357;
1358 X_SUB WMEM
1359 X_WORD_OP
1360;
1361; (OP) mem (END)
1362;
1363 X_SUB OP_MEM
1364 DB Z_OP, Z_MEM, Z_END
1365
1366;
1367; TEST
1368; reg, immed
1369; mem, immed
1370;
1371P_TEST2 LABEL BYTE
1372 X_CALL TTEST
1373 X_MEM
1374 X_COMMA
1375 DB Z_IMMED, Z_END
1376
1377;
1378; TEST
1379; accum, immed
1380;
1381P_TEST3 LABEL BYTE
1382 X_CALL TTEST
1383 X_ACCUM
1384 X_COMMA
1385 DB Z_IMMED, Z_END
1386
1387;
1388; XCHG
1389; reg, reg
1390; reg, mem
1391;
1392P_XCHG1 DB "XCHG", Z_OP
1393 X_CALL REG_MEM ; reg, mem (END)
1394
1395;
1396; XCHG
1397; accum, reg
1398;
1399P_XCHG2 DB "XCHG", Z_OP, Z_ACCUM
1400 X_COMMA
1401 DB Z_REGA, Z_END
1402
1403
1404P_NOT DB "NOT"
1405 X_CALL OP_MEM
1406
1407P_NEG DB "NEG"
1408 X_CALL OP_MEM
1409
1410P_IMUL DB "I"
1411P_MUL DB "MUL"
1412 X_CALL OP_MEM
1413
1414P_IDIV DB "I"
1415P_DIV DB "DIV"
1416 X_CALL OP_MEM
1417
1418P_IMUL_IMMED DB "IMUL", Z_OP
1419 X_WORD_OP
1420 X_NOT
1421 X_TEST 02H, P_IMUL_I_1
1422 X_SIGNED
1423P_IMUL_I_1 DB Z_MOD_REG_RM
1424 X_REG
1425 X_COMMA
1426 X_MEM
1427 X_COMMA
1428 DB Z_IMMED, Z_END
1429
1430P_IMUL_MEM DB "IMUL"
1431 X_WORD_OP
1432 X_CALL OP_REG_MEM
1433
1434P_RETN DB "RETN"
1435 X_JUMP P_RET
1436P_RETF DB "RETF"
1437P_RET LABEL BYTE
1438 X_EMPTY
1439 X_TEST 01H, P_RET_1
1440 X_OP
1441 X_WORD
1442P_RET_1 DB Z_END
1443
1444P_LEA DB "LEA", Z_OP
1445 X_CALL REG_MEM ; reg, mem (END)
1446
1447;
1448; MOV
1449; reg, reg
1450; mem, reg
1451; reg, mem
1452;
1453P_MOV1 LABEL BYTE
1454 X_CALL TMOV
1455 X_JUMP DIRECTION
1456
1457;
1458; MOV
1459; mem, immed
1460;
1461P_MOV2 LABEL BYTE
1462 X_CALL TMOV
1463 DB Z_MOD_REG_RM, Z_MEM
1464 X_COMMA
1465 DB Z_IMMED, Z_END
1466
1467;
1468; MOV
1469; reg, immed
1470;
1471P_MOV3B LABEL BYTE
1472 X_BYTE_OP
1473 X_JUMP P_MOV3
1474
1475P_MOV3W LABEL BYTE
1476 X_WORD_OP
1477P_MOV3 LABEL BYTE
1478 X_CALL TMOV
1479 X_REGA
1480 X_COMMA
1481 DB Z_IMMED, Z_END
1482;
1483; MOV
1484; mem, accum
1485; accum, mem
1486P_MOV4 LABEL BYTE
1487 X_CALL TMOV
1488 X_TEST 02H, P_MOV4_1
1489 X_ACCUM
1490 X_COMMA
1491 X_DISP
1492 X_END
1493P_MOV4_1 LABEL BYTE
1494 X_DISP
1495 X_COMMA
1496 DB Z_ACCUM, Z_END
1497
1498;
1499; MOV
1500; sreg, reg
1501; sreg, mem
1502; reg, sreg
1503; mem, sreg
1504;
1505P_MOV5 LABEL BYTE
1506 X_CALL TMOV
1507 X_MOD_REG_RM
1508 X_WORD_OP
1509 X_TEST 02H, P_MOV5_1
1510 X_MEM
1511 X_COMMA
1512 X_LOAD_REG
1513 X_CALL SREG
1514 X_END
1515P_MOV5_1 LABEL BYTE
1516 X_LOAD_REG
1517 X_CALL SREG
1518 X_COMMA
1519 DB Z_MEM, Z_END
1520
1521
1522;
1523; ADD, OR, ADC, SBB, AND, SUB, XOR, CMP
1524; reg, reg
1525; mem, reg
1526; reg, mem
1527;
1528P_ARITH1 LABEL BYTE
1529 X_BITS 38H
1530 X_CALL ARITH
1531 X_OP
1532DIRECTION LABEL BYTE
1533 X_MOD_REG_RM
1534 X_OPCODE
1535 X_TEST 02H, DIR1 ; d=1?
1536 X_MEM
1537 X_COMMA
1538 DB Z_REG, Z_END
1539DIR1 DB Z_REG
1540 X_COMMA
1541 DB Z_MEM, Z_END
1542
1543;
1544; ADD, OR, ADC, SBB, AND, SUB, XOR, CMP
1545; reg, immed
1546; mem, immed
1547;
1548P_ARITH2 LABEL BYTE
1549 X_NOT
1550 X_TEST 02H, P_ARITH2_1 ; s=0?
1551 X_SIGNED
1552P_ARITH2_1 LABEL BYTE
1553 X_MOD_REG_RM
1554 X_LOAD_REG
1555 X_CALL ARITH
1556 X_OP
1557 X_MEM
1558 X_COMMA
1559 DB Z_IMMED, Z_END
1560
1561;
1562; ADD, OR, ADC, SBB, AND, SUB, XOR, CMP
1563; accum, immed
1564;
1565P_ARITH3 LABEL BYTE
1566 X_BITS 38H
1567 X_CALL ARITH
1568 DB Z_OP, Z_ACCUM
1569 X_COMMA
1570 DB Z_IMMED, Z_END
1571
1572;
1573; Insert arimthmetic instruction ?????aaa)
1574;
1575 X_SUB ARITH
1576 X_BITS 07H
1577 X_TABLE
1578 DW ARITH00, ARITH01, ARITH02, ARITH03
1579 DW ARITH04, ARITH05, ARITH06, ARITH07
1580
1581ARITH00 DB "ADD", Z_RET
1582ARITH02 DB "ADC", Z_RET
1583ARITH03 DB "SBB", Z_RET
1584ARITH04 DB "AND", Z_RET
1585ARITH05 DB "SUB", Z_RET
1586ARITH06 DB "X"
1587ARITH01 DB "OR", Z_RET
1588ARITH07 DB "CMP", Z_RET
1589
1590;
1591; Insert condition code (accu = ????cccc)
1592;
1593 X_SUB COND
1594 X_BITS 0FH
1595 X_TABLE
1596 DW COND00, COND01, COND02, COND03
1597 DW COND04, COND05, COND06, COND07
1598 DW COND08, COND09, COND0A, COND0B
1599 DW COND0C, COND0D, COND0E, COND0F
1600COND01 DB "N"
1601COND00 DB "O", Z_RET
1602COND03 DB "N"
1603COND02 DB "C", Z_RET
1604COND05 DB "N"
1605COND04 DB "E", Z_RET
1606COND06 DB "BE", Z_RET
1607COND07 DB "A", Z_RET
1608COND09 DB "N"
1609COND08 DB "S", Z_RET
1610COND0A DB "PE", Z_RET
1611COND0B DB "PO", Z_RET
1612COND0C DB "L", Z_RET
1613COND0D DB "GE", Z_RET
1614COND0E DB "LE", Z_RET
1615COND0F DB "G", Z_RET
1616
1617
1618;
1619; Insert segment register (accu = ?????sss)
1620;
1621 X_SUB SREG
1622 X_CALL SREG_1
1623 DB "S", Z_RET
1624
1625 X_SUB SREG_1
1626 X_BITS 07H
1627 X_TABLE
1628 DW SREG00, SREG01, SREG02, SREG03
1629 DW SREG04, SREG05, SREG06, SREG07
1630
1631SREG00 DB "E", Z_RET
1632SREG01 DB "C", Z_RET
1633SREG02 DB "S", Z_RET
1634SREG03 DB "D", Z_RET
1635SREG04 DB "F", Z_RET
1636SREG05 DB "G", Z_RET
1637SREG06 DB "?", Z_RET
1638SREG07 DB "?", Z_RET
1639
1640;
1641; Insert special register (reg = ?????qqq)
1642; Caller must insert "C", "D", or "T" before calling this subroutine
1643;
1644 X_SUB SPECIAL
1645 DB "R"
1646 X_LOAD_REG
1647 X_NIBBLE
1648 X_RET
1649
1650
1651;
1652; Insert "D" if operand size = 32
1653; Does not return!
1654;
1655 X_SUB APPEND_D
1656 X_O16 APPEND_D1
1657 DB "D"
1658APPEND_D1 DB Z_END
1659
1660;
1661; Operand separator
1662;
1663 X_SUB P_COMMA
1664 DB ", ", Z_RET
1665
1666
1667;
1668; Load reg field of mod,reg,r/m into accu
1669;
1670 X_SUB P_LOAD_REG
1671 X_LD_MOD_REG_RM
1672 X_BITS 00111000B
1673 X_RET
1674
1675
1676;
1677; Floating point
1678;
1679
1680P_ESC DB "F"
1681 X_OPCODE ; Opcode -> accu
1682 X_PUSH ; Push opcode
1683 X_MORE ; Get next byte
1684 X_MASK_EQ 0C0H, 0C0H, ESC_REG ; mod = 11 ->
1685 X_BACK ; Back to mod,reg,r/m
1686 X_MOD_REG_RM
1687 X_NO_PTR
1688 X_POP
1689 X_BITS 07H
1690 X_TABLE
1691 DW NPXMEM_D8, NPXMEM_D9, NPXMEM_DA, NPXMEM_DB
1692 DW NPXMEM_DC, NPXMEM_DD, NPXMEM_DE, NPXMEM_DF
1693
1694ESC_REG LABEL BYTE
1695 X_XCHG ; Get 1st byte, save 2nd
1696 X_BITS 07H
1697 X_TABLE
1698 DW NPXREG_D8, NPXREG_D9, NPXREG_DA, NPXREG_DB
1699 DW NPXREG_DC, NPXREG_DD, NPXREG_DE, NPXREG_DF
1700
1701
1702NPXMEM_DA LABEL BYTE ; 32-bit real
1703NPXMEM_DE LABEL BYTE ; Integer
1704 DB "I"
1705NPXMEM_D8 LABEL BYTE ; 32-bit real
1706NPXMEM_DC LABEL BYTE ; 64-bit real
1707 X_LD_MOD_REG_RM
1708 X_CALL NPX1
1709 X_OP
1710 X_MEM
1711 X_END
1712
1713
1714NPXMEM_D9 LABEL BYTE
1715 X_LD_MOD_REG_RM
1716 X_CALL NPX3
1717 X_OP
1718 X_MEM
1719 X_END
1720
1721 X_SUB NPX3
1722 X_BITS 38H
1723 X_TABLE
1724 DW P_LD, NPX_FAILURE, P_ST, P_STP
1725 DW P_LDENV, P_LDCW, P_STENV, P_STCW
1726
1727P_LDENV DB "LDENV", Z_RET
1728P_LDCW DB "LDCW", Z_RET
1729P_STENV DB "STENV", Z_RET
1730P_STCW DB "STCW", Z_RET
1731
1732NPXMEM_DB LABEL BYTE
1733 X_LD_MOD_REG_RM
1734 X_CALL NPX4
1735 X_OP
1736 X_MEM
1737 X_END
1738
1739 X_SUB NPX4
1740 X_BITS 38H
1741 X_TABLE
1742 DW P_ILD, NPX_FAILURE, P_IST, P_ISTP
1743 DW NPX_FAILURE, P_LD, NPX_FAILURE, P_STP
1744
1745P_ILD DB "I"
1746P_LD DB "LD", Z_RET
1747P_IST DB "I"
1748P_ST DB "ST", Z_RET
1749P_ISTP DB "I"
1750P_STP DB "STP", Z_RET
1751
1752NPXMEM_DD LABEL BYTE
1753 X_LD_MOD_REG_RM
1754 X_CALL NPX5
1755 X_OP
1756 X_MEM
1757 X_END
1758
1759 X_SUB NPX5
1760 X_BITS 38H
1761 X_TABLE
1762 DW P_LD, NPX_FAILURE, P_ST, P_STP
1763 DW P_RSTOR, NPX_FAILURE, P_SAVE, P_STSW
1764
1765P_RSTOR DB "RSTOR", Z_RET
1766P_SAVE DB "SAVE", Z_RET
1767P_STSW DB "STSW", Z_RET
1768
1769
1770NPXMEM_DF LABEL BYTE
1771 X_LD_MOD_REG_RM
1772 X_CALL NPX6
1773 X_OP
1774 X_MEM
1775 X_END
1776
1777 X_SUB NPX6
1778 X_BITS 38H
1779 X_TABLE
1780 DW P_ILD, NPX_FAILURE, P_IST, P_ISTP
1781 DW P_BLD, P_ILD, P_BSTP, P_ISTP
1782
1783P_BLD DB "BLD", Z_RET
1784P_BSTP DB "BSTP", Z_RET
1785
1786NPXREG_D8 LABEL BYTE
1787 X_POP
1788 X_PUSH
1789 X_CALL NPX1
1790 X_POP
1791 DB Z_OP, "ST"
1792 X_COMMA
1793 X_CALL FREG
1794 X_END
1795
1796NPXREG_DC LABEL BYTE
1797 X_POP
1798 X_PUSH
1799 X_CALL NPX2
1800 X_POP
1801 X_OP
1802 X_CALL FREG
1803 X_COMMA
1804 DB "ST"
1805 X_END
1806
1807 X_SUB NPX1
1808 X_BITS 38H
1809 X_TABLE
1810 DW NPX_ADD, NPX_MUL, NPX_COM, NPX_COMP
1811 DW NPX_SUB, NPX_SUBR, NPX_DIV, NPX_DIVR
1812
1813 X_SUB NPX2
1814 X_BITS 38H
1815 X_TABLE
1816 DW NPX_ADD, NPX_MUL, NPX_COM, NPX_COMP
1817 DW NPX_SUBR, NPX_SUB, NPX_DIVR, NPX_DIV
1818
1819NPX_ADD DB "ADD", Z_RET
1820NPX_MUL DB "MUL", Z_RET
1821NPX_COM DB "COM", Z_RET
1822NPX_COMP DB "COMP", Z_RET
1823NPX_SUB DB "SUB", Z_RET
1824NPX_SUBR DB "SUBR", Z_RET
1825NPX_DIV DB "DIV", Z_RET
1826NPX_DIVR DB "DIVR", Z_RET
1827
1828NPXREG_D9 LABEL BYTE
1829 X_POP
1830 X_PUSH
1831 X_BITS 38H
1832 X_TABLE
1833 DW NPXREG_D9_0, NPXREG_D9_1, NPXREG_D9_2, NPX_FAILURE
1834 DW NPXREG_D9_4, NPXREG_D9_5, NPXREG_D9_67, NPXREG_D9_67
1835
1836NPXREG_D9_0 DB "LD"
1837 X_CALL NPX_ST
1838NPXREG_D9_1 DB "XCH"
1839 X_CALL NPX_ST
1840NPXREG_D9_2 DB "NOP"
1841 X_CALL NPX_ST
1842
1843NPXREG_D9_4 LABEL BYTE
1844 X_POP
1845 X_BITS 07H
1846 X_TABLE
1847 DW NPXREG_D9_4_0, NPXREG_D9_4_1, NPX_FAILURE, NPX_FAILURE
1848 DW NPXREG_D9_4_4, NPXREG_D9_4_5, NPX_FAILURE, NPX_FAILURE
1849
1850NPXREG_D9_4_0 DB "CHS", Z_END
1851NPXREG_D9_4_1 DB "ABS", Z_END
1852NPXREG_D9_4_4 DB "TST", Z_END
1853NPXREG_D9_4_5 DB "XAM", Z_END
1854
1855NPXREG_D9_5 DB "LD"
1856 X_POP
1857 X_BITS 07H
1858 X_TABLE
1859 DW NPXREG_D9_5_0, NPXREG_D9_5_1, NPXREG_D9_5_2, NPXREG_D9_5_3
1860 DW NPXREG_D9_5_4, NPXREG_D9_5_5, NPXREG_D9_5_6, NPX_FAILURE
1861
1862NPXREG_D9_5_0 DB "1", Z_END
1863NPXREG_D9_5_1 DB "2T", Z_END
1864NPXREG_D9_5_2 DB "2E", Z_END
1865NPXREG_D9_5_3 DB "PI", Z_END
1866NPXREG_D9_5_4 DB "LG2", Z_END
1867NPXREG_D9_5_5 DB "LN2", Z_END
1868NPXREG_D9_5_6 DB "Z", Z_END
1869
1870NPXREG_D9_67 LABEL BYTE
1871 X_POP
1872 X_BITS 0FH
1873 X_TABLE
1874 DW NPXREG_D9_6_0, NPXREG_D9_6_1, NPXREG_D9_6_2, NPXREG_D9_6_3
1875 DW NPXREG_D9_6_4, NPXREG_D9_6_5, NPXREG_D9_6_6, NPXREG_D9_6_7
1876 DW NPXREG_D9_7_0, NPXREG_D9_7_1, NPXREG_D9_7_2, NPXREG_D9_7_3
1877 DW NPXREG_D9_7_4, NPXREG_D9_7_5, NPXREG_D9_7_6, NPXREG_D9_7_7
1878
1879NPXREG_D9_6_0 DB "2XM1", Z_END
1880NPXREG_D9_6_1 DB "YL2X", Z_END
1881NPXREG_D9_6_2 DB "PTAN", Z_END
1882NPXREG_D9_6_3 DB "PATAN", Z_END
1883NPXREG_D9_6_4 DB "XTRACT", Z_END
1884NPXREG_D9_6_5 DB "PREM1", Z_END
1885NPXREG_D9_6_6 DB "DECSTP", Z_END
1886NPXREG_D9_6_7 DB "INCSTP", Z_END
1887NPXREG_D9_7_0 DB "PREM", Z_END
1888NPXREG_D9_7_1 DB "YL2XP1", Z_END
1889NPXREG_D9_7_2 DB "SQRT", Z_END
1890NPXREG_D9_7_3 DB "SINCOS", Z_END
1891NPXREG_D9_7_4 DB "RNDINT", Z_END
1892NPXREG_D9_7_5 DB "SCALE", Z_END
1893NPXREG_D9_7_6 DB "SIN", Z_END
1894NPXREG_D9_7_7 DB "COS", Z_END
1895
1896
1897NPXREG_DA LABEL BYTE
1898 X_POP
1899 X_SWITCH
1900 X_CASE 0E9H, NPXREG_DA_E9
1901 X_JUMP NPX_FAILURE
1902
1903NPXREG_DA_E9 DB "U"
1904NPXREG_DE_D9 DB "COMPP", Z_END
1905
1906NPXREG_DB LABEL BYTE
1907 X_POP
1908 X_SWITCH
1909 X_CASE 0E2H, NPXREG_DB_E2
1910 X_CASE 0E3H, NPXREG_DB_E3
1911 X_JUMP NPX_FAILURE
1912
1913NPXREG_DB_E2 DB "CLEX", Z_END
1914NPXREG_DB_E3 DB "INIT", Z_END
1915
1916NPXREG_DD LABEL BYTE
1917 X_POP
1918 X_PUSH
1919 X_BITS 38H
1920 X_TABLE
1921 DW NPXREG_DD_0, NPXREG_DD_1, NPXREG_DD_2, NPXREG_DD_3
1922 DW NPXREG_DD_4, NPXREG_DD_5, NPX_FAILURE, NPX_FAILURE
1923
1924NPXREG_DD_0 DB "FREE"
1925 X_CALL NPX_ST
1926NPXREG_DD_1 DB "XCH"
1927 X_CALL NPX_ST
1928NPXREG_DD_2 DB "ST"
1929 X_CALL NPX_ST
1930NPXREG_DD_3 DB "STP"
1931 X_CALL NPX_ST
1932NPXREG_DD_4 DB "UCOM"
1933 X_CALL NPX_ST
1934NPXREG_DD_5 DB "UCOMP"
1935 X_CALL NPX_ST
1936
1937NPXREG_DE LABEL BYTE
1938 X_POP
1939 X_SWITCH
1940 X_CASE 0D9H, NPXREG_DE_D9
1941 X_PUSH
1942 X_CALL NPX2
1943 X_POP
1944 DB "P"
1945 X_CALL NPX_ST
1946
1947NPXREG_DF LABEL BYTE
1948 X_POP
1949 X_SWITCH
1950 X_CASE 0E0H, NPXREG_DF_E0
1951 X_JUMP NPX_FAILURE
1952
1953NPXREG_DF_E0 DB "STSW", Z_OP, "AX", Z_END
1954
1955
1956;
1957; Insert "<Tab>ST(accu)" and end
1958;
1959
1960 X_SUB NPX_ST
1961 X_OP
1962 X_CALL FREG
1963 X_END
1964
1965;
1966; Insert ST(accu)
1967;
1968 X_SUB FREG
1969 DB "ST("
1970 X_BITS 07H
1971 X_NIBBLE
1972 DB ")"
1973 X_RET
1974
1975
1976NPX_FAILURE DB "???", Z_END
1977
1978
1979; ============================================================================
1980; End of disassembler language program
1981; ============================================================================
1982
1983
1984DISASM_CALL LABEL WORD
1985CIDX = 0
1986 REPT CALLCNT
1987 VDW CALLV, %CIDX
1988CIDX = CIDX + 1
1989 ENDM
1990SV_DATA ENDS
1991
1992
1993
1994
1995
1996SV_CODE SEGMENT
1997
1998 ASSUME CS:SV_CODE, DS:SV_DATA
1999
2000
2001XCHAR MACRO CHR
2002 MOV BYTE PTR DS:[DI], CHR
2003 INC DI
2004 ENDM
2005
2006
2007XTEXT PROC NEAR
2008 PUSH AX
2009 PUSH BX
2010 MOV BX, DX
2011XTEXT1: MOV AL, [BX]
2012 OR AL, AL
2013 JZ SHORT XTEXT9
2014 XCHAR AL
2015 INC BX
2016 JMP SHORT XTEXT1
2017XTEXT9: POP BX
2018 POP AX
2019 RET
2020XTEXT ENDP
2021
2022
2023XDWORD PROC NEAR
2024 ROR EAX, 16
2025 CALL XWORD
2026 ROR EAX, 16
2027 CALL XWORD
2028 RET
2029XDWORD ENDP
2030
2031XWORD PROC NEAR
2032 XCHG AL, AH
2033 CALL XBYTE
2034 XCHG AL, AH
2035 CALL XBYTE
2036 RET
2037XWORD ENDP
2038
2039
2040XBYTE PROC NEAR
2041 PUSH AX
2042 SHR AL, 4
2043 CALL XNIBBLE
2044 POP AX
2045 PUSH AX
2046 CALL XNIBBLE
2047 POP AX
2048 RET
2049XBYTE ENDP
2050
2051XNIBBLE PROC NEAR
2052 AND AL, 0FH
2053 ADD AL, 30H
2054 CMP AL, 3AH
2055 JB SHORT XNIB1
2056 ADD AL, 7
2057XNIB1: XCHAR AL
2058 RET
2059XNIBBLE ENDP
2060
2061
2062XSBYTE PROC NEAR
2063 PUSH AX
2064 TEST AL, 80H
2065 JNZ SHORT XSBYTE2
2066 XCHAR "+"
2067XSBYTE1: CALL XBYTE
2068 POP AX
2069 RET
2070XSBYTE2: XCHAR "-"
2071 NEG AL
2072 JMP SHORT XSBYTE1
2073XSBYTE ENDP
2074
2075
2076;
2077; In: AL Bits 0..2: register number
2078; OPSIZE operand size (0=BYTE, 1=WORD)
2079; PFX_OSIZE Operand size
2080;
2081XREG PROC NEAR
2082 PUSH AX
2083 PUSH BX
2084 LEA BX, $REG8
2085 CMP OPSIZE, 0
2086 JE SHORT XREG1
2087 LEA BX, $REG16
2088 CALL OSIZE ; Operand size
2089 JZ SHORT XREG1 ; 16 ->
2090 XCHAR "E"
2091XREG1: AND AX, 07H
2092 SHL AX, 1
2093 ADD BX, AX
2094 MOV AX, [BX]
2095 XCHAR AL
2096 XCHAR AH
2097 POP BX
2098 POP AX
2099 RET
2100XREG ENDP
2101
2102
2103;
2104; In: AL Register number (bits 0..2)
2105;
2106REG32 PROC NEAR
2107 XCHAR "E"
2108REG16 PROC NEAR
2109 PUSH AX
2110 PUSH BX
2111 MOV BL, AL
2112 AND BX, 07H
2113 SHL BX, 1
2114 MOV AX, WORD PTR $REG16[BX]
2115 XCHAR AL
2116 XCHAR AH
2117 POP BX
2118 POP AX
2119 RET
2120REG16 ENDP
2121REG32 ENDP
2122
2123
2124
2125;
2126; In: OPSIZE
2127; FLAGS
2128;
2129XIMMED PROC NEAR
2130 CMP OPSIZE, 0
2131 JNE SHORT XIMMED_WORD
2132 MOV AL, FS:[ESI]
2133 INC ESI
2134 CALL XBYTE
2135 RET
2136
2137XIMMED_WORD: TEST FLAGS, F_SIGNED ; s?
2138 JZ SHORT XIMMED_WORD1 ; No ->
2139 MOV AL, FS:[ESI]
2140 INC ESI
2141 CALL XSBYTE
2142 RET
2143
2144XIMMED_WORD1: CALL OSIZE ; Operand size
2145 JZ SHORT XIMMED_WORD2 ; 16 ->
2146 MOV EAX, FS:[ESI]
2147 ADD ESI, 4
2148 MOV SYM_ADDR, EAX
2149 MOV SYM_FLAG, SYM_ANY
2150 CALL XDWORD
2151 RET
2152
2153XIMMED_WORD2: MOV AX, FS:[ESI]
2154 ADD ESI, 2
2155 CALL XWORD
2156 RET
2157XIMMED ENDP
2158
2159
2160;
2161; Return address size
2162;
2163; Out: NZ 32 bit
2164; ZR 16 bit
2165;
2166ASIZE PROC NEAR
2167 CMP MODE_32, 0
2168 JE SHORT ASIZE16
2169ASIZE32: CMP PFX_ASIZE, SIZE_ON
2170 RET
2171ASIZE16: CMP PFX_ASIZE, SIZE_OFF
2172 RET
2173ASIZE ENDP
2174
2175
2176;
2177; Return operand size
2178;
2179; Out: NZ 32 bit
2180; ZR 16 bit
2181;
2182OSIZE PROC NEAR
2183 CMP MODE_32, 0
2184 JE SHORT OSIZE16
2185OSIZE32: CMP PFX_OSIZE, SIZE_ON
2186 RET
2187OSIZE16: CMP PFX_OSIZE, SIZE_OFF
2188 RET
2189OSIZE ENDP
2190
2191
2192
2193;
2194;
2195; In: FS:ESI Source
2196; DS:DI Destination
2197; ECX Value of EIP at FS:ESI (ESI, if no relocation used)
2198; AL address/operand size: 0:16, 1:32
2199;
2200; Out: DS:DI Pointer to terminating byte of destination (0)
2201; AL SYM_NONE=no symbol; SYM_ANY, SYM_TEXT, SYM_DATA
2202; AH Non-zero, if an empty line should be output after this line
2203; EDX Symbol address (if AL<>SYM_NONE)
2204;
2205DISASM PROC NEAR
2206 SUB ECX, ESI
2207 MOV RELOCATION, ECX
2208 MOV MODE_32, AL
2209 MOV PFX_ASIZE, SIZE_OFF
2210 MOV PFX_OSIZE, SIZE_OFF
2211 MOV PFX_SEG, 0
2212 MOV DISASM_SP, OFFSET SV_DATA:DISASM_STACK
2213 MOV ACCU_SP, OFFSET SV_DATA:ACCU_STACK
2214 MOV NOT_FLAG, 0
2215 MOV FLAGS, 0
2216 MOV SYM_FLAG, SYM_NONE
2217DISASM_FETCH:: LEA BX, DISASM_PROGRAM
2218DISASM_MORE:: MOV AL, FS:[ESI]
2219 INC ESI
2220 MOV ACCU, AL
2221 MOV OPCODE, AL
2222 AND AL, 01H
2223 MOV OPSIZE, AL
2224DISASM_NEXT: MOV CL, [BX]
2225 INC BX
2226 CMP CL, 20H ; Command?
2227 JB SHORT DISASM1 ; Yes ->
2228 CMP CL, 80H ; Subroutine call?
2229 JAE SHORT DISASM2 ; Yes ->
2230 XCHAR CL
2231 JMP SHORT DISASM_NEXT
2232
2233DISASM1: MOVZX ECX, CL
2234 CALL DISASM_JMP[ECX*2]
2235 JMP SHORT DISASM_NEXT
2236
2237DISASM2: MOVZX ECX, CL
2238 MOV DX, BX
2239 SUB DISASM_SP, 2
2240 MOV BX, DISASM_SP
2241 MOV [BX], DX
2242 MOV BX, DISASM_CALL[ECX*2-80H*2]
2243 JMP SHORT DISASM_NEXT
2244
2245DISASM ENDP
2246
2247
2248Q_END: POP AX
2249 MOV BYTE PTR [DI], 0
2250 MOV AL, SYM_FLAG
2251 MOV AH, FLAGS
2252 AND AH, F_EMPTY
2253 MOV EDX, SYM_ADDR
2254 RET
2255
2256Q_MORE: POP AX
2257 JMP DISASM_MORE
2258
2259Q_EXT: MOV CL, [BX]
2260 INC BX
2261 CMP CL, 4
2262 JAE Q_END
2263 MOVZX ECX, CL
2264 JMP EXT_JMP[ECX*2]
2265
2266Q_PREFIX: MOV DX, [BX+0]
2267 MOV AL, [BX+2]
2268 MOV BX, DX
2269 MOV [BX], AL
2270 POP AX
2271 JMP DISASM_FETCH
2272
2273Q_RET: MOV BX, DISASM_SP
2274 MOV BX, [BX]
2275 ADD DISASM_SP, 2
2276 RET
2277
2278Q_OPCODE: MOV AL, OPCODE
2279 MOV ACCU, AL
2280 RET
2281
2282Q_NOT: XOR NOT_FLAG, 1
2283 RET
2284
2285
2286Q_OP: XCHAR TAB
2287 RET
2288
2289Q_FLAGS: MOV AL, [BX]
2290 INC BX
2291 OR FLAGS, AL
2292 RET
2293
2294Q_JMP_DST: MOV AL, [BX]
2295 INC BX
2296 CMP AL, 1
2297 JE SHORT Q_NEAR
2298 CMP AL, 2
2299 JE Q_FAR
2300Q_SHORT: MOVSX EAX, BYTE PTR FS:[ESI]
2301 INC ESI
2302 JMP SHORT DNEAR2
2303
2304Q_NEAR: CALL ASIZE
2305 JNZ SHORT DNEAR1
2306 MOVSX EAX, WORD PTR FS:[ESI]
2307 ADD ESI, 2
2308 JMP SHORT DNEAR2
2309DNEAR1: MOV EAX, FS:[ESI]
2310 ADD ESI, 4
2311DNEAR2: ADD EAX, ESI
2312 ADD EAX, RELOCATION
2313 MOV SYM_ADDR, EAX
2314 MOV SYM_FLAG, SYM_TEXT
2315 CALL XDWORD
2316 RET
2317
2318
2319Q_SWITCH: MOVZX ECX, BYTE PTR [BX]
2320 INC BX
2321 JECXZ DSWITCH9
2322DSWITCH1: MOV AL, [BX+0]
2323 CMP ACCU, AL
2324 JE SHORT DSWITCH2
2325 ADD BX, 3
2326 LOOP DSWITCH1
2327DSWITCH9: RET
2328
2329DSWITCH2: MOV BX, [BX+1]
2330 RET
2331
2332Q_MASK_EQ: MOV DL, [BX+0]
2333 MOV DH, [BX+1]
2334 ADD BX, 2
2335 MOV AL, ACCU
2336 AND AL, DL
2337 CMP AL, DH
2338 SETE AL
2339COND_JUMP: CMP AL, NOT_FLAG
2340 MOV NOT_FLAG, 0
2341 JNE SHORT Q_JUMP
2342 ADD BX, 2
2343 RET
2344
2345Q_JUMP: MOV BX, [BX]
2346 RET
2347
2348Q_LD_MOD_REG_RM:MOV AL, MOD_REG_RM
2349 MOV ACCU, AL
2350 RET
2351
2352Q_TEST: MOV AL, [BX]
2353 INC BX
2354 TEST ACCU, AL
2355 SETNE AL
2356 JMP COND_JUMP
2357
2358Q_BITS: MOVZX DX, BYTE PTR [BX]
2359 INC BX
2360 BSF CX, DX
2361 AND ACCU, DL
2362 SHR ACCU, CL
2363 RET
2364
2365Q_CMP: MOV DX, [BX+0]
2366 MOV AL, [BX+2]
2367 ADD BX, 3
2368 XCHG BX, DX
2369 CMP AL, [BX]
2370 SETE AL
2371 XCHG BX, DX
2372 JMP COND_JUMP
2373
2374Q_IMMED: CALL XIMMED
2375 AND FLAGS, NOT F_SIGNED
2376 RET
2377
2378Q_MOD_REG_RM: MOV AL, FS:[ESI] ; mod,reg,r/m
2379 INC ESI
2380 MOV MOD_REG_RM, AL
2381 CALL ASIZE ; Address size
2382 JZ SHORT Q_MOD_REG_RM_9 ; 16 ->
2383 CMP AL, 0C0H ; mod=11?
2384 JAE SHORT Q_MOD_REG_RM_9 ; Yes -> no SIB
2385 AND AL, 07H ; r/m
2386 CMP AL, 04H ; SIB?
2387 JNE SHORT Q_MOD_REG_RM_9 ; No ->
2388 MOV AL, FS:[ESI]
2389 INC ESI
2390 MOV SIB, AL
2391Q_MOD_REG_RM_9: RET
2392
2393
2394Q_REG: MOV AL, MOD_REG_RM
2395 SHR AL, 3
2396 CALL XREG
2397 RET
2398
2399Q_REGA: MOV AL, ACCU
2400 CALL XREG
2401 RET
2402
2403Q_MEM: MOV AL, MOD_REG_RM
2404 CMP AL, 40H
2405 JB SHORT QMEM00
2406 CMP AL, 80H
2407 JB SHORT QMEM01
2408 CMP AL, 0C0H
2409 JB SHORT QMEM10
2410QMEM11: CALL XREG
2411 RET
2412
2413QMEM00: AND AL, 07H ; r/m
2414 MOV AH, 06H
2415 CALL ASIZE ; Address size
2416 JZ SHORT QMEM00_1 ; 16 -> 6 is special case
2417 MOV AH, 05H ; 32 -> 5 is special case
2418QMEM00_1: CMP AL, AH
2419 JE SHORT QMEM00_2
2420 CALL QMEM_IND
2421 JMP SHORT QMEM_END
2422
2423QMEM00_2: CALL QMEM_BEGIN
2424 CALL QMEM_DISPW
2425 JMP SHORT QMEM_END
2426
2427QMEM01: CALL QMEM_IND
2428 MOV AL, FS:[ESI]
2429 INC ESI
2430 CALL XSBYTE
2431QMEM_END: XCHAR "]"
2432 RET
2433
2434QMEM10: CALL QMEM_IND
2435 XCHAR "+"
2436 CALL QMEM_DISPW
2437 JMP SHORT QMEM_END
2438
2439
2440QMEM_BEGIN PROC NEAR
2441 TEST FLAGS, F_NO_PTR
2442 JNZ SHORT QMEM_B2A
2443 LEA DX, $BYTE
2444 CMP OPSIZE, 00H ; byte
2445 JE SHORT QMEM_B2
2446 LEA DX, $DWORD
2447 CMP OPSIZE, 01H ; word
2448 JE SHORT QMEM_B1
2449 CALL OSIZE ; Operand size
2450 JZ SHORT QMEM_B2 ; 16 ->
2451 XCHAR "f"
2452 INC DX
2453 JMP SHORT QMEM_B2
2454QMEM_B1: CALL OSIZE ; Operand size
2455 JNZ SHORT QMEM_B2 ; 32 ->
2456 INC DX
2457QMEM_B2: CALL XTEXT
2458 LEA DX, $PTR
2459 CALL XTEXT
2460QMEM_B2A: MOV AL, PFX_SEG
2461 OR AL, AL
2462 JZ SHORT QMEM_B3
2463 XCHAR AL
2464 XCHAR "S"
2465 XCHAR ":"
2466QMEM_B3: XCHAR "["
2467 RET
2468QMEM_BEGIN ENDP
2469
2470QMEM_IND PROC NEAR
2471 CALL QMEM_BEGIN
2472 MOV AL, MOD_REG_RM
2473 AND AL, 07H ; r/m
2474 CALL ASIZE ; Address size
2475 JNZ SHORT QMEM_IND32 ; 32 ->
2476 PUSH BX
2477 LEA BX, RM_TAB
2478 XLAT
2479 MOV BX, "BX"
2480 MOV AH, 01H
2481 CALL QMEM_IND1
2482 MOV BX, "BP"
2483 MOV AH, 02H
2484 CALL QMEM_IND1
2485 MOV BX, "SI"
2486 MOV AH, 04H
2487 CALL QMEM_IND1
2488 MOV BX, "DI"
2489 MOV AH, 08H
2490 CALL QMEM_IND1
2491 POP BX
2492 RET
2493
2494QMEM_IND32: CMP AL, 04H
2495 JE SHORT QMEM_SIB
2496 CALL REG32
2497 RET
2498
2499QMEM_SIB: MOV AL, SIB
2500 AND AL, 07H ; base
2501 CMP MOD_REG_RM, 40H ; mod=0?
2502 JAE SHORT QMEM_SIB1 ; No -> normal case
2503 CMP AL, 05H ; base=5?
2504 JNE SHORT QMEM_SIB1 ; No -> normal case
2505 CALL QMEM_DISPW ; disp32+(scale*index)
2506 JMP SHORT QMEM_SIB2
2507
2508QMEM_SIB1: MOV AL, SIB
2509 CALL REG32
2510QMEM_SIB2: MOV AL, SIB
2511 AND AL, 7 SHL 3
2512 CMP AL, 4 SHL 3
2513 JE SHORT QMEM_SIB4
2514 XCHAR "+"
2515 MOV AL, SIB
2516 SHR AL, 6
2517 AND AL, 03H
2518 JZ SHORT QMEM_SIB3
2519 MOV CL, AL
2520 MOV AL, 01H
2521 SHL AL, CL
2522 ADD AL, "0"
2523 XCHAR AL
2524 XCHAR "*"
2525QMEM_SIB3: MOV AL, SIB
2526 SHR AL, 3
2527 CALL REG32
2528QMEM_SIB4: RET
2529
2530QMEM_IND ENDP
2531
2532
2533
2534QMEM_IND1 PROC NEAR
2535 TEST AL, AH
2536 JZ SHORT QMEM_IND9
2537 TEST AL, 80H
2538 JZ SHORT QMEM_IND2
2539 XCHAR "+"
2540QMEM_IND2: OR AL, 80H
2541 CALL ASIZE ; Address size
2542 JZ SHORT QMEM_IND3 ; 16 ->
2543 XCHAR "E"
2544QMEM_IND3: XCHAR BH
2545 XCHAR BL
2546QMEM_IND9: RET
2547QMEM_IND1 ENDP
2548
2549
2550Q_ACCUM: MOV AL, 0
2551 CALL XREG
2552 RET
2553
2554Q_NIBBLE: MOV AL, ACCU
2555 CALL XNIBBLE
2556 RET
2557
2558Q_O16: CALL OSIZE ; Operand size
2559 SETZ AL ; 16 -> AL:=1
2560 JMP COND_JUMP
2561
2562Q_A16: CALL ASIZE ; Address size
2563 SETZ AL ; 16 -> AL:=1
2564 JMP COND_JUMP
2565
2566Q_BYTE: MOV AL, FS:[ESI]
2567 INC ESI
2568 CALL XBYTE
2569 RET
2570
2571QMEM_DISPW: CALL ASIZE ; Address size
2572 JZ SHORT Q_WORD ; 16 ->
2573 CALL Q_DWORD
2574 MOV SYM_ADDR, EAX
2575 MOV SYM_FLAG, SYM_DATA
2576 RET
2577
2578Q_DISP: XCHAR "["
2579 CALL QMEM_DISPW
2580 XCHAR "]"
2581 RET
2582
2583Q_DWORD: MOV EAX, FS:[ESI]
2584 ADD ESI, 4
2585 CALL XDWORD
2586 RET
2587
2588Q_WORD: MOV AX, FS:[ESI]
2589 ADD ESI, 2
2590 CALL XWORD
2591 RET
2592
2593Q_TABLE: MOVZX AX, ACCU
2594 SHL AX, 1
2595 ADD BX, AX
2596 MOV BX, [BX]
2597 RET
2598
2599Q_OP_SIZE: MOV AL, [BX]
2600 INC BX
2601 MOV OPSIZE, AL
2602 RET
2603
2604Q_FAR: CALL ASIZE ; Address size
2605 JNZ SHORT DFAR1 ; 32 ->
2606 MOVZX ECX, WORD PTR FS:[ESI] ; Oops, was MOVSX
2607 ADD ESI, 2
2608 JMP SHORT DFAR2
2609DFAR1: MOV ECX, FS:[ESI] ; Get offset
2610 ADD ESI, 4
2611DFAR2: MOV AX, FS:[ESI] ; Get selector
2612 ADD ESI, 2 ; Skip selector
2613 CALL XWORD ; Output selector
2614 XCHAR ":"
2615 MOV EAX, ECX ; Oops, adding ESI was wrong!
2616 CALL XDWORD ; Output offset
2617 RET
2618
2619Q_PUSH: PUSH BX
2620 DEC ACCU_SP
2621 MOV BX, ACCU_SP
2622 MOV AL, ACCU
2623 MOV [BX], AL
2624 POP BX
2625 RET
2626
2627Q_POP: PUSH BX
2628 MOV BX, ACCU_SP
2629 MOV AL, [BX]
2630 MOV ACCU, AL
2631 INC ACCU_SP
2632 POP BX
2633 RET
2634
2635Q_XCHG: PUSH BX
2636 MOV BX, ACCU_SP
2637 MOV AL, ACCU
2638 XCHG AL, [BX]
2639 MOV ACCU, AL
2640 POP BX
2641 RET
2642
2643Q_BACK: DEC ESI
2644 RET
2645
2646SV_CODE ENDS
2647
2648 ELSE
2649
2650;
2651; No disassembler
2652;
2653SV_CODE SEGMENT
2654
2655 ASSUME CS:SV_CODE, DS:NOTHING
2656
2657DISASM PROC NEAR
2658 INC ESI
2659 RET
2660DISASM ENDP
2661
2662SV_CODE ENDS
2663
2664 ENDIF
2665
2666 END
Note: See TracBrowser for help on using the repository browser.