]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/i386/db_disasm.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
28 * Revision 1.1.1.1 1998/09/22 21:05:36 wsanchez
29 * Import of Mac OS X kernel (~semeria)
31 * Revision 1.1.1.1 1998/03/07 02:25:37 wsanchez
32 * Import of OSF Mach kernel (~mburg)
34 * Revision 1.2.8.3 1996/07/31 09:43:35 paire
35 * Merged with nmk20b7_shared (1.2.11.1)
38 * Revision 1.2.11.1 1996/05/14 13:49:36 paire
39 * Added support for new cmpxchg8b, cpuid, rdtsc, rdwmr, rsm and wrmsr
40 * Pentium instructions
43 * Revision 1.2.8.2 1994/09/23 01:50:45 ezf
44 * change marker to not FREE
45 * [1994/09/22 21:21:17 ezf]
47 * Revision 1.2.8.1 1994/09/16 15:26:28 emcmanus
48 * Only skip over GAS-inserted NOPs after branches if they are really
49 * NOPs; this depends at least on assembler options.
50 * [1994/09/16 15:26:03 emcmanus]
52 * Revision 1.2.6.3 1994/02/19 15:40:34 bolinger
53 * For load/store counting, mark all varieties of "call" as writing
55 * [1994/02/15 20:25:18 bolinger]
57 * Revision 1.2.6.2 1994/02/14 21:46:49 dwm
59 * [1994/02/14 21:46:14 dwm]
61 * Revision 1.2.6.1 1994/02/12 23:26:05 bolinger
62 * Implement load/store counting for ddb "until" command.
63 * [1994/02/12 03:34:55 bolinger]
65 * Revision 1.2.2.3 1993/08/09 19:39:21 dswartz
66 * Add ANSI prototypes - CR#9523
67 * [1993/08/06 17:44:13 dswartz]
69 * Revision 1.2.2.2 1993/06/09 02:27:29 gm
70 * Added to OSF/1 R1.3 from NMK15.0.
71 * [1993/06/02 21:03:54 jeffc]
73 * Revision 1.2 1993/04/19 16:12:57 devrcs
74 * Print file names and lineno on branch instructions.
78 * Revision 1.1 1992/09/30 02:02:19 robert
85 * Revision 2.5.3.1 92/03/03 16:14:27 jeffreyh
86 * Pick up changes from TRUNK
87 * [92/02/26 11:05:06 jeffreyh]
89 * Revision 2.6 92/01/03 20:05:00 dbg
90 * Add a switch to disassemble 16-bit code.
91 * Fix spelling of 'lods' opcodes.
94 * Revision 2.5 91/10/09 16:05:58 af
95 * Supported disassemble of non current task by passing task parameter.
98 * Revision 2.4 91/05/14 16:05:04 mrt
99 * Correcting copyright
101 * Revision 2.3 91/02/05 17:11:03 mrt
102 * Changed to new Mach copyright
103 * [91/02/01 17:31:03 mrt]
105 * Revision 2.2 90/08/27 21:55:56 dbg
106 * Fix register operand for move to/from control/test/debug
107 * register instructions. Add i486 instructions.
110 * Import db_sym.h. Print instruction displacements in
111 * current radix (signed). Change calling sequence of
122 * Mach Operating System
123 * Copyright (c) 1991,1990 Carnegie Mellon University
124 * All Rights Reserved.
126 * Permission to use, copy, modify and distribute this software and its
127 * documentation is hereby granted, provided that both the copyright
128 * notice and this permission notice appear in all copies of the
129 * software, derivative works or modified versions, and any portions
130 * thereof, and that both notices appear in supporting documentation.
132 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
133 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
134 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
136 * Carnegie Mellon requests users of this software to return to
138 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
139 * School of Computer Science
140 * Carnegie Mellon University
141 * Pittsburgh PA 15213-3890
143 * any improvements or extensions that they make and grant Carnegie Mellon
144 * the rights to redistribute these changes.
150 * Instruction disassembler.
153 #include <mach/boolean.h>
154 #include <machine/db_machdep.h>
156 #include <ddb/db_access.h>
157 #include <ddb/db_sym.h>
158 #include <ddb/db_output.h>
160 #include <kern/task.h>
161 #include <kern/misc_protos.h>
164 int is_reg
; /* if reg, reg number is in 'disp' */
173 extern db_addr_t
db_read_address(
177 struct i_addr
* addrp
,
179 extern void db_print_address(
182 struct i_addr
*addrp
,
184 extern db_addr_t
db_disasm_esc(
193 * Switch to disassemble 16-bit code.
195 boolean_t db_disasm_16
= FALSE
;
213 #define E 1 /* general effective address */
214 #define Eind 2 /* indirect address (jump, call) */
215 #define Ew 3 /* address, word size */
216 #define Eb 4 /* address, byte size */
217 #define R 5 /* register, in 'reg' field */
218 #define Rw 6 /* word register, in 'reg' field */
219 #define Ri 7 /* register in instruction */
220 #define S 8 /* segment reg, in 'reg' field */
221 #define Si 9 /* segment reg, in instruction */
222 #define A 10 /* accumulator */
223 #define BX 11 /* (bx) */
224 #define CL 12 /* cl, for shifts */
225 #define DX 13 /* dx, for IO */
226 #define SI 14 /* si */
227 #define DI 15 /* di */
228 #define CR 16 /* control register */
229 #define DR 17 /* debug register */
230 #define TR 18 /* test register */
231 #define I 19 /* immediate, unsigned */
232 #define Is 20 /* immediate, signed */
233 #define Ib 21 /* byte immediate, unsigned */
234 #define Ibs 22 /* byte immediate, signed */
235 #define Iw 23 /* word immediate, unsigned */
236 #define Il 24 /* long immediate */
237 #define O 25 /* direct address */
238 #define Db 26 /* byte displacement from EIP */
239 #define Dl 27 /* long displacement from EIP */
240 #define o1 28 /* constant 1 */
241 #define o3 29 /* constant 3 */
242 #define OS 30 /* immediate offset/segment */
243 #define ST 31 /* FP stack top */
244 #define STI 32 /* FP stack */
245 #define X 33 /* extended FP op */
246 #define XA 34 /* for 'fstcw %ax' */
249 char * i_name
; /* name */
250 short i_has_modrm
; /* has regmodrm byte */
251 short i_size
; /* operand size */
252 int i_mode
; /* addressing modes */
253 char * i_extra
; /* pointer to extra opcode table */
257 #define op2(x,y) ((x)|((y)<<8))
258 #define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
261 char * f_name
; /* name for memory instruction */
262 int f_size
; /* size for memory instruction */
263 int f_rrmode
; /* mode for rr instruction */
264 char * f_rrname
; /* name for rr instruction
265 (or pointer to table) */
301 struct inst db_inst_0f0x
[] = {
302 /*00*/ { "", TRUE
, NONE
, op1(Ew
), (char *)db_Grp6
},
303 /*01*/ { "", TRUE
, NONE
, op1(Ew
), (char *)db_Grp7
},
304 /*02*/ { "lar", TRUE
, LONG
, op2(E
,R
), 0 },
305 /*03*/ { "lsl", TRUE
, LONG
, op2(E
,R
), 0 },
306 /*04*/ { "", FALSE
, NONE
, 0, 0 },
307 /*05*/ { "", FALSE
, NONE
, 0, 0 },
308 /*06*/ { "clts", FALSE
, NONE
, 0, 0 },
309 /*07*/ { "", FALSE
, NONE
, 0, 0 },
311 /*08*/ { "invd", FALSE
, NONE
, 0, 0 },
312 /*09*/ { "wbinvd",FALSE
, NONE
, 0, 0 },
313 /*0a*/ { "", FALSE
, NONE
, 0, 0 },
314 /*0b*/ { "", FALSE
, NONE
, 0, 0 },
315 /*0c*/ { "", FALSE
, NONE
, 0, 0 },
316 /*0d*/ { "", FALSE
, NONE
, 0, 0 },
317 /*0e*/ { "", FALSE
, NONE
, 0, 0 },
318 /*0f*/ { "", FALSE
, NONE
, 0, 0 },
321 struct inst db_inst_0f2x
[] = {
322 /*20*/ { "mov", TRUE
, LONG
, op2(CR
,E
), 0 }, /* use E for reg */
323 /*21*/ { "mov", TRUE
, LONG
, op2(DR
,E
), 0 }, /* since mod == 11 */
324 /*22*/ { "mov", TRUE
, LONG
, op2(E
,CR
), 0 },
325 /*23*/ { "mov", TRUE
, LONG
, op2(E
,DR
), 0 },
326 /*24*/ { "mov", TRUE
, LONG
, op2(TR
,E
), 0 },
327 /*25*/ { "", FALSE
, NONE
, 0, 0 },
328 /*26*/ { "mov", TRUE
, LONG
, op2(E
,TR
), 0 },
329 /*27*/ { "", FALSE
, NONE
, 0, 0 },
331 /*28*/ { "", FALSE
, NONE
, 0, 0 },
332 /*29*/ { "", FALSE
, NONE
, 0, 0 },
333 /*2a*/ { "", FALSE
, NONE
, 0, 0 },
334 /*2b*/ { "", FALSE
, NONE
, 0, 0 },
335 /*2c*/ { "", FALSE
, NONE
, 0, 0 },
336 /*2d*/ { "", FALSE
, NONE
, 0, 0 },
337 /*2e*/ { "", FALSE
, NONE
, 0, 0 },
338 /*2f*/ { "", FALSE
, NONE
, 0, 0 },
340 struct inst db_inst_0f3x
[] = {
341 /*30*/ { "rdtsc", FALSE
, NONE
, 0, 0 },
342 /*31*/ { "rdmsr", FALSE
, NONE
, 0, 0 },
343 /*32*/ { "wrmsr", FALSE
, NONE
, 0, 0 },
344 /*33*/ { "", FALSE
, NONE
, 0, 0 },
345 /*34*/ { "", FALSE
, NONE
, 0, 0 },
346 /*35*/ { "", FALSE
, NONE
, 0, 0 },
347 /*36*/ { "", FALSE
, NONE
, 0, 0 },
348 /*37*/ { "", FALSE
, NONE
, 0, 0 },
350 /*38*/ { "", FALSE
, NONE
, 0, 0 },
351 /*39*/ { "", FALSE
, NONE
, 0, 0 },
352 /*3a*/ { "", FALSE
, NONE
, 0, 0 },
353 /*3b*/ { "", FALSE
, NONE
, 0, 0 },
354 /*3c*/ { "", FALSE
, NONE
, 0, 0 },
355 /*3d*/ { "", FALSE
, NONE
, 0, 0 },
356 /*3e*/ { "", FALSE
, NONE
, 0, 0 },
357 /*3f*/ { "", FALSE
, NONE
, 0, 0 },
360 struct inst db_inst_0f8x
[] = {
361 /*80*/ { "jo", FALSE
, NONE
, op1(Dl
), 0 },
362 /*81*/ { "jno", FALSE
, NONE
, op1(Dl
), 0 },
363 /*82*/ { "jb", FALSE
, NONE
, op1(Dl
), 0 },
364 /*83*/ { "jnb", FALSE
, NONE
, op1(Dl
), 0 },
365 /*84*/ { "jz", FALSE
, NONE
, op1(Dl
), 0 },
366 /*85*/ { "jnz", FALSE
, NONE
, op1(Dl
), 0 },
367 /*86*/ { "jbe", FALSE
, NONE
, op1(Dl
), 0 },
368 /*87*/ { "jnbe", FALSE
, NONE
, op1(Dl
), 0 },
370 /*88*/ { "js", FALSE
, NONE
, op1(Dl
), 0 },
371 /*89*/ { "jns", FALSE
, NONE
, op1(Dl
), 0 },
372 /*8a*/ { "jp", FALSE
, NONE
, op1(Dl
), 0 },
373 /*8b*/ { "jnp", FALSE
, NONE
, op1(Dl
), 0 },
374 /*8c*/ { "jl", FALSE
, NONE
, op1(Dl
), 0 },
375 /*8d*/ { "jnl", FALSE
, NONE
, op1(Dl
), 0 },
376 /*8e*/ { "jle", FALSE
, NONE
, op1(Dl
), 0 },
377 /*8f*/ { "jnle", FALSE
, NONE
, op1(Dl
), 0 },
380 struct inst db_inst_0f9x
[] = {
381 /*90*/ { "seto", TRUE
, NONE
, op1(Eb
), 0 },
382 /*91*/ { "setno", TRUE
, NONE
, op1(Eb
), 0 },
383 /*92*/ { "setb", TRUE
, NONE
, op1(Eb
), 0 },
384 /*93*/ { "setnb", TRUE
, NONE
, op1(Eb
), 0 },
385 /*94*/ { "setz", TRUE
, NONE
, op1(Eb
), 0 },
386 /*95*/ { "setnz", TRUE
, NONE
, op1(Eb
), 0 },
387 /*96*/ { "setbe", TRUE
, NONE
, op1(Eb
), 0 },
388 /*97*/ { "setnbe",TRUE
, NONE
, op1(Eb
), 0 },
390 /*98*/ { "sets", TRUE
, NONE
, op1(Eb
), 0 },
391 /*99*/ { "setns", TRUE
, NONE
, op1(Eb
), 0 },
392 /*9a*/ { "setp", TRUE
, NONE
, op1(Eb
), 0 },
393 /*9b*/ { "setnp", TRUE
, NONE
, op1(Eb
), 0 },
394 /*9c*/ { "setl", TRUE
, NONE
, op1(Eb
), 0 },
395 /*9d*/ { "setnl", TRUE
, NONE
, op1(Eb
), 0 },
396 /*9e*/ { "setle", TRUE
, NONE
, op1(Eb
), 0 },
397 /*9f*/ { "setnle",TRUE
, NONE
, op1(Eb
), 0 },
400 struct inst db_inst_0fax
[] = {
401 /*a0*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
402 /*a1*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
403 /*a2*/ { "cpuid", FALSE
, NONE
, 0, 0 },
404 /*a3*/ { "bt", TRUE
, LONG
, op2(E
,R
), 0 },
405 /*a4*/ { "shld", TRUE
, LONG
, op3(Ib
,E
,R
), 0 },
406 /*a5*/ { "shld", TRUE
, LONG
, op3(CL
,E
,R
), 0 },
407 /*a6*/ { "", FALSE
, NONE
, 0, 0 },
408 /*a7*/ { "", FALSE
, NONE
, 0, 0 },
410 /*a8*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
411 /*a9*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
412 /*aa*/ { "rsm", FALSE
, NONE
, 0, 0 },
413 /*ab*/ { "bts", TRUE
, LONG
, op2(E
,R
), 0 },
414 /*ac*/ { "shrd", TRUE
, LONG
, op3(Ib
,E
,R
), 0 },
415 /*ad*/ { "shrd", TRUE
, LONG
, op3(CL
,E
,R
), 0 },
416 /*a6*/ { "", FALSE
, NONE
, 0, 0 },
417 /*a7*/ { "imul", TRUE
, LONG
, op2(E
,R
), 0 },
420 struct inst db_inst_0fbx
[] = {
421 /*b0*/ { "", FALSE
, NONE
, 0, 0 },
422 /*b1*/ { "", FALSE
, NONE
, 0, 0 },
423 /*b2*/ { "lss", TRUE
, LONG
, op2(E
, R
), 0 },
424 /*b3*/ { "bts", TRUE
, LONG
, op2(R
, E
), 0 },
425 /*b4*/ { "lfs", TRUE
, LONG
, op2(E
, R
), 0 },
426 /*b5*/ { "lgs", TRUE
, LONG
, op2(E
, R
), 0 },
427 /*b6*/ { "movzb", TRUE
, LONG
, op2(E
, R
), 0 },
428 /*b7*/ { "movzw", TRUE
, LONG
, op2(E
, R
), 0 },
430 /*b8*/ { "", FALSE
, NONE
, 0, 0 },
431 /*b9*/ { "", FALSE
, NONE
, 0, 0 },
432 /*ba*/ { "", TRUE
, LONG
, op2(Is
, E
), (char *)db_Grp8
},
433 /*bb*/ { "btc", TRUE
, LONG
, op2(R
, E
), 0 },
434 /*bc*/ { "bsf", TRUE
, LONG
, op2(E
, R
), 0 },
435 /*bd*/ { "bsr", TRUE
, LONG
, op2(E
, R
), 0 },
436 /*be*/ { "movsb", TRUE
, LONG
, op2(E
, R
), 0 },
437 /*bf*/ { "movsw", TRUE
, LONG
, op2(E
, R
), 0 },
440 struct inst db_inst_0fcx
[] = {
441 /*c0*/ { "xadd", TRUE
, BYTE
, op2(R
, E
), 0 },
442 /*c1*/ { "xadd", TRUE
, LONG
, op2(R
, E
), 0 },
443 /*c2*/ { "", FALSE
, NONE
, 0, 0 },
444 /*c3*/ { "", FALSE
, NONE
, 0, 0 },
445 /*c4*/ { "", FALSE
, NONE
, 0, 0 },
446 /*c5*/ { "", FALSE
, NONE
, 0, 0 },
447 /*c6*/ { "", FALSE
, NONE
, 0, 0 },
448 /*c7*/ { "cmpxchg8b", FALSE
, NONE
, op1(E
), 0 },
449 /*c8*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
450 /*c9*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
451 /*ca*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
452 /*cb*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
453 /*cc*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
454 /*cd*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
455 /*ce*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
456 /*cf*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
459 struct inst db_inst_0fdx
[] = {
460 /*c0*/ { "cmpxchg",TRUE
, BYTE
, op2(R
, E
), 0 },
461 /*c1*/ { "cmpxchg",TRUE
, LONG
, op2(R
, E
), 0 },
462 /*c2*/ { "", FALSE
, NONE
, 0, 0 },
463 /*c3*/ { "", FALSE
, NONE
, 0, 0 },
464 /*c4*/ { "", FALSE
, NONE
, 0, 0 },
465 /*c5*/ { "", FALSE
, NONE
, 0, 0 },
466 /*c6*/ { "", FALSE
, NONE
, 0, 0 },
467 /*c7*/ { "", FALSE
, NONE
, 0, 0 },
468 /*c8*/ { "", FALSE
, NONE
, 0, 0 },
469 /*c9*/ { "", FALSE
, NONE
, 0, 0 },
470 /*ca*/ { "", FALSE
, NONE
, 0, 0 },
471 /*cb*/ { "", FALSE
, NONE
, 0, 0 },
472 /*cc*/ { "", FALSE
, NONE
, 0, 0 },
473 /*cd*/ { "", FALSE
, NONE
, 0, 0 },
474 /*ce*/ { "", FALSE
, NONE
, 0, 0 },
475 /*cf*/ { "", FALSE
, NONE
, 0, 0 },
478 struct inst
*db_inst_0f
[] = {
497 char * db_Esc92
[] = {
498 "fnop", "", "", "", "", "", "", ""
500 char * db_Esc93
[] = {
501 "", "", "", "", "", "", "", ""
503 char * db_Esc94
[] = {
504 "fchs", "fabs", "", "", "ftst", "fxam", "", ""
506 char * db_Esc95
[] = {
507 "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
509 char * db_Esc96
[] = {
510 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
513 char * db_Esc97
[] = {
514 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
517 char * db_Esca4
[] = {
518 "", "fucompp","", "", "", "", "", ""
521 char * db_Escb4
[] = {
522 "", "", "fnclex","fninit","", "", "", ""
525 char * db_Esce3
[] = {
526 "", "fcompp","", "", "", "", "", ""
529 char * db_Escf4
[] = {
530 "fnstsw","", "", "", "", "", "", ""
533 struct finst db_Esc8
[] = {
534 /*0*/ { "fadd", SNGL
, op2(STI
,ST
), 0 },
535 /*1*/ { "fmul", SNGL
, op2(STI
,ST
), 0 },
536 /*2*/ { "fcom", SNGL
, op2(STI
,ST
), 0 },
537 /*3*/ { "fcomp", SNGL
, op2(STI
,ST
), 0 },
538 /*4*/ { "fsub", SNGL
, op2(STI
,ST
), 0 },
539 /*5*/ { "fsubr", SNGL
, op2(STI
,ST
), 0 },
540 /*6*/ { "fdiv", SNGL
, op2(STI
,ST
), 0 },
541 /*7*/ { "fdivr", SNGL
, op2(STI
,ST
), 0 },
544 struct finst db_Esc9
[] = {
545 /*0*/ { "fld", SNGL
, op1(STI
), 0 },
546 /*1*/ { "", NONE
, op1(STI
), "fxch" },
547 /*2*/ { "fst", SNGL
, op1(X
), (char *)db_Esc92
},
548 /*3*/ { "fstp", SNGL
, op1(X
), (char *)db_Esc93
},
549 /*4*/ { "fldenv", NONE
, op1(X
), (char *)db_Esc94
},
550 /*5*/ { "fldcw", NONE
, op1(X
), (char *)db_Esc95
},
551 /*6*/ { "fnstenv",NONE
, op1(X
), (char *)db_Esc96
},
552 /*7*/ { "fnstcw", NONE
, op1(X
), (char *)db_Esc97
},
555 struct finst db_Esca
[] = {
556 /*0*/ { "fiadd", WORD
, 0, 0 },
557 /*1*/ { "fimul", WORD
, 0, 0 },
558 /*2*/ { "ficom", WORD
, 0, 0 },
559 /*3*/ { "ficomp", WORD
, 0, 0 },
560 /*4*/ { "fisub", WORD
, op1(X
), (char *)db_Esca4
},
561 /*5*/ { "fisubr", WORD
, 0, 0 },
562 /*6*/ { "fidiv", WORD
, 0, 0 },
563 /*7*/ { "fidivr", WORD
, 0, 0 }
566 struct finst db_Escb
[] = {
567 /*0*/ { "fild", WORD
, 0, 0 },
568 /*1*/ { "", NONE
, 0, 0 },
569 /*2*/ { "fist", WORD
, 0, 0 },
570 /*3*/ { "fistp", WORD
, 0, 0 },
571 /*4*/ { "", WORD
, op1(X
), (char *)db_Escb4
},
572 /*5*/ { "fld", EXTR
, 0, 0 },
573 /*6*/ { "", WORD
, 0, 0 },
574 /*7*/ { "fstp", EXTR
, 0, 0 },
577 struct finst db_Escc
[] = {
578 /*0*/ { "fadd", DBLR
, op2(ST
,STI
), 0 },
579 /*1*/ { "fmul", DBLR
, op2(ST
,STI
), 0 },
580 /*2*/ { "fcom", DBLR
, op2(ST
,STI
), 0 },
581 /*3*/ { "fcomp", DBLR
, op2(ST
,STI
), 0 },
582 /*4*/ { "fsub", DBLR
, op2(ST
,STI
), "fsubr" },
583 /*5*/ { "fsubr", DBLR
, op2(ST
,STI
), "fsub" },
584 /*6*/ { "fdiv", DBLR
, op2(ST
,STI
), "fdivr" },
585 /*7*/ { "fdivr", DBLR
, op2(ST
,STI
), "fdiv" },
588 struct finst db_Escd
[] = {
589 /*0*/ { "fld", DBLR
, op1(STI
), "ffree" },
590 /*1*/ { "", NONE
, 0, 0 },
591 /*2*/ { "fst", DBLR
, op1(STI
), 0 },
592 /*3*/ { "fstp", DBLR
, op1(STI
), 0 },
593 /*4*/ { "frstor", NONE
, op1(STI
), "fucom" },
594 /*5*/ { "", NONE
, op1(STI
), "fucomp" },
595 /*6*/ { "fnsave", NONE
, 0, 0 },
596 /*7*/ { "fnstsw", NONE
, 0, 0 },
599 struct finst db_Esce
[] = {
600 /*0*/ { "fiadd", LONG
, op2(ST
,STI
), "faddp" },
601 /*1*/ { "fimul", LONG
, op2(ST
,STI
), "fmulp" },
602 /*2*/ { "ficom", LONG
, 0, 0 },
603 /*3*/ { "ficomp", LONG
, op1(X
), (char *)db_Esce3
},
604 /*4*/ { "fisub", LONG
, op2(ST
,STI
), "fsubrp" },
605 /*5*/ { "fisubr", LONG
, op2(ST
,STI
), "fsubp" },
606 /*6*/ { "fidiv", LONG
, op2(ST
,STI
), "fdivrp" },
607 /*7*/ { "fidivr", LONG
, op2(ST
,STI
), "fdivp" },
610 struct finst db_Escf
[] = {
611 /*0*/ { "fild", LONG
, 0, 0 },
612 /*1*/ { "", LONG
, 0, 0 },
613 /*2*/ { "fist", LONG
, 0, 0 },
614 /*3*/ { "fistp", LONG
, 0, 0 },
615 /*4*/ { "fbld", NONE
, op1(XA
), (char *)db_Escf4
},
616 /*5*/ { "fld", QUAD
, 0, 0 },
617 /*6*/ { "fbstp", NONE
, 0, 0 },
618 /*7*/ { "fstp", QUAD
, 0, 0 },
621 struct finst
*db_Esc_inst
[] = {
622 db_Esc8
, db_Esc9
, db_Esca
, db_Escb
,
623 db_Escc
, db_Escd
, db_Esce
, db_Escf
648 struct inst db_Grp3
[] = {
649 { "test", TRUE
, NONE
, op2(I
,E
), 0 },
650 { "test", TRUE
, NONE
, op2(I
,E
), 0 },
651 { "not", TRUE
, NONE
, op1(E
), 0 },
652 { "neg", TRUE
, NONE
, op1(E
), 0 },
653 { "mul", TRUE
, NONE
, op2(E
,A
), 0 },
654 { "imul", TRUE
, NONE
, op2(E
,A
), 0 },
655 { "div", TRUE
, NONE
, op2(E
,A
), 0 },
656 { "idiv", TRUE
, NONE
, op2(E
,A
), 0 },
659 struct inst db_Grp4
[] = {
660 { "inc", TRUE
, BYTE
, op1(E
), 0 },
661 { "dec", TRUE
, BYTE
, op1(E
), 0 },
662 { "", TRUE
, NONE
, 0, 0 },
663 { "", TRUE
, NONE
, 0, 0 },
664 { "", TRUE
, NONE
, 0, 0 },
665 { "", TRUE
, NONE
, 0, 0 },
666 { "", TRUE
, NONE
, 0, 0 },
667 { "", TRUE
, NONE
, 0, 0 }
670 struct inst db_Grp5
[] = {
671 { "inc", TRUE
, LONG
, op1(E
), 0 },
672 { "dec", TRUE
, LONG
, op1(E
), 0 },
673 { "call", TRUE
, NONE
, op1(Eind
),0 },
674 { "lcall", TRUE
, NONE
, op1(Eind
),0 },
675 { "jmp", TRUE
, NONE
, op1(Eind
),0 },
676 { "ljmp", TRUE
, NONE
, op1(Eind
),0 },
677 { "push", TRUE
, LONG
, op1(E
), 0 },
678 { "", TRUE
, NONE
, 0, 0 }
681 struct inst db_inst_table
[256] = {
682 /*00*/ { "add", TRUE
, BYTE
, op2(R
, E
), 0 },
683 /*01*/ { "add", TRUE
, LONG
, op2(R
, E
), 0 },
684 /*02*/ { "add", TRUE
, BYTE
, op2(E
, R
), 0 },
685 /*03*/ { "add", TRUE
, LONG
, op2(E
, R
), 0 },
686 /*04*/ { "add", FALSE
, BYTE
, op2(Is
, A
), 0 },
687 /*05*/ { "add", FALSE
, LONG
, op2(Is
, A
), 0 },
688 /*06*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
689 /*07*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
691 /*08*/ { "or", TRUE
, BYTE
, op2(R
, E
), 0 },
692 /*09*/ { "or", TRUE
, LONG
, op2(R
, E
), 0 },
693 /*0a*/ { "or", TRUE
, BYTE
, op2(E
, R
), 0 },
694 /*0b*/ { "or", TRUE
, LONG
, op2(E
, R
), 0 },
695 /*0c*/ { "or", FALSE
, BYTE
, op2(I
, A
), 0 },
696 /*0d*/ { "or", FALSE
, LONG
, op2(I
, A
), 0 },
697 /*0e*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
698 /*0f*/ { "", FALSE
, NONE
, 0, 0 },
700 /*10*/ { "adc", TRUE
, BYTE
, op2(R
, E
), 0 },
701 /*11*/ { "adc", TRUE
, LONG
, op2(R
, E
), 0 },
702 /*12*/ { "adc", TRUE
, BYTE
, op2(E
, R
), 0 },
703 /*13*/ { "adc", TRUE
, LONG
, op2(E
, R
), 0 },
704 /*14*/ { "adc", FALSE
, BYTE
, op2(Is
, A
), 0 },
705 /*15*/ { "adc", FALSE
, LONG
, op2(Is
, A
), 0 },
706 /*16*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
707 /*17*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
709 /*18*/ { "sbb", TRUE
, BYTE
, op2(R
, E
), 0 },
710 /*19*/ { "sbb", TRUE
, LONG
, op2(R
, E
), 0 },
711 /*1a*/ { "sbb", TRUE
, BYTE
, op2(E
, R
), 0 },
712 /*1b*/ { "sbb", TRUE
, LONG
, op2(E
, R
), 0 },
713 /*1c*/ { "sbb", FALSE
, BYTE
, op2(Is
, A
), 0 },
714 /*1d*/ { "sbb", FALSE
, LONG
, op2(Is
, A
), 0 },
715 /*1e*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
716 /*1f*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
718 /*20*/ { "and", TRUE
, BYTE
, op2(R
, E
), 0 },
719 /*21*/ { "and", TRUE
, LONG
, op2(R
, E
), 0 },
720 /*22*/ { "and", TRUE
, BYTE
, op2(E
, R
), 0 },
721 /*23*/ { "and", TRUE
, LONG
, op2(E
, R
), 0 },
722 /*24*/ { "and", FALSE
, BYTE
, op2(I
, A
), 0 },
723 /*25*/ { "and", FALSE
, LONG
, op2(I
, A
), 0 },
724 /*26*/ { "", FALSE
, NONE
, 0, 0 },
725 /*27*/ { "aaa", FALSE
, NONE
, 0, 0 },
727 /*28*/ { "sub", TRUE
, BYTE
, op2(R
, E
), 0 },
728 /*29*/ { "sub", TRUE
, LONG
, op2(R
, E
), 0 },
729 /*2a*/ { "sub", TRUE
, BYTE
, op2(E
, R
), 0 },
730 /*2b*/ { "sub", TRUE
, LONG
, op2(E
, R
), 0 },
731 /*2c*/ { "sub", FALSE
, BYTE
, op2(Is
, A
), 0 },
732 /*2d*/ { "sub", FALSE
, LONG
, op2(Is
, A
), 0 },
733 /*2e*/ { "", FALSE
, NONE
, 0, 0 },
734 /*2f*/ { "das", FALSE
, NONE
, 0, 0 },
736 /*30*/ { "xor", TRUE
, BYTE
, op2(R
, E
), 0 },
737 /*31*/ { "xor", TRUE
, LONG
, op2(R
, E
), 0 },
738 /*32*/ { "xor", TRUE
, BYTE
, op2(E
, R
), 0 },
739 /*33*/ { "xor", TRUE
, LONG
, op2(E
, R
), 0 },
740 /*34*/ { "xor", FALSE
, BYTE
, op2(I
, A
), 0 },
741 /*35*/ { "xor", FALSE
, LONG
, op2(I
, A
), 0 },
742 /*36*/ { "", FALSE
, NONE
, 0, 0 },
743 /*37*/ { "daa", FALSE
, NONE
, 0, 0 },
745 /*38*/ { "cmp", TRUE
, BYTE
, op2(R
, E
), 0 },
746 /*39*/ { "cmp", TRUE
, LONG
, op2(R
, E
), 0 },
747 /*3a*/ { "cmp", TRUE
, BYTE
, op2(E
, R
), 0 },
748 /*3b*/ { "cmp", TRUE
, LONG
, op2(E
, R
), 0 },
749 /*3c*/ { "cmp", FALSE
, BYTE
, op2(Is
, A
), 0 },
750 /*3d*/ { "cmp", FALSE
, LONG
, op2(Is
, A
), 0 },
751 /*3e*/ { "", FALSE
, NONE
, 0, 0 },
752 /*3f*/ { "aas", FALSE
, NONE
, 0, 0 },
754 /*40*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
755 /*41*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
756 /*42*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
757 /*43*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
758 /*44*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
759 /*45*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
760 /*46*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
761 /*47*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
763 /*48*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
764 /*49*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
765 /*4a*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
766 /*4b*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
767 /*4c*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
768 /*4d*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
769 /*4e*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
770 /*4f*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
772 /*50*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
773 /*51*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
774 /*52*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
775 /*53*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
776 /*54*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
777 /*55*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
778 /*56*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
779 /*57*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
781 /*58*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
782 /*59*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
783 /*5a*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
784 /*5b*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
785 /*5c*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
786 /*5d*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
787 /*5e*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
788 /*5f*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
790 /*60*/ { "pusha", FALSE
, LONG
, 0, 0 },
791 /*61*/ { "popa", FALSE
, LONG
, 0, 0 },
792 /*62*/ { "bound", TRUE
, LONG
, op2(E
, R
), 0 },
793 /*63*/ { "arpl", TRUE
, NONE
, op2(Ew
,Rw
), 0 },
795 /*64*/ { "", FALSE
, NONE
, 0, 0 },
796 /*65*/ { "", FALSE
, NONE
, 0, 0 },
797 /*66*/ { "", FALSE
, NONE
, 0, 0 },
798 /*67*/ { "", FALSE
, NONE
, 0, 0 },
800 /*68*/ { "push", FALSE
, LONG
, op1(I
), 0 },
801 /*69*/ { "imul", TRUE
, LONG
, op3(I
,E
,R
), 0 },
802 /*6a*/ { "push", FALSE
, LONG
, op1(Ib
), 0 },
803 /*6b*/ { "imul", TRUE
, LONG
, op3(Ibs
,E
,R
),0 },
804 /*6c*/ { "ins", FALSE
, BYTE
, op2(DX
, DI
), 0 },
805 /*6d*/ { "ins", FALSE
, LONG
, op2(DX
, DI
), 0 },
806 /*6e*/ { "outs", FALSE
, BYTE
, op2(SI
, DX
), 0 },
807 /*6f*/ { "outs", FALSE
, LONG
, op2(SI
, DX
), 0 },
809 /*70*/ { "jo", FALSE
, NONE
, op1(Db
), 0 },
810 /*71*/ { "jno", FALSE
, NONE
, op1(Db
), 0 },
811 /*72*/ { "jb", FALSE
, NONE
, op1(Db
), 0 },
812 /*73*/ { "jnb", FALSE
, NONE
, op1(Db
), 0 },
813 /*74*/ { "jz", FALSE
, NONE
, op1(Db
), 0 },
814 /*75*/ { "jnz", FALSE
, NONE
, op1(Db
), 0 },
815 /*76*/ { "jbe", FALSE
, NONE
, op1(Db
), 0 },
816 /*77*/ { "jnbe", FALSE
, NONE
, op1(Db
), 0 },
818 /*78*/ { "js", FALSE
, NONE
, op1(Db
), 0 },
819 /*79*/ { "jns", FALSE
, NONE
, op1(Db
), 0 },
820 /*7a*/ { "jp", FALSE
, NONE
, op1(Db
), 0 },
821 /*7b*/ { "jnp", FALSE
, NONE
, op1(Db
), 0 },
822 /*7c*/ { "jl", FALSE
, NONE
, op1(Db
), 0 },
823 /*7d*/ { "jnl", FALSE
, NONE
, op1(Db
), 0 },
824 /*7e*/ { "jle", FALSE
, NONE
, op1(Db
), 0 },
825 /*7f*/ { "jnle", FALSE
, NONE
, op1(Db
), 0 },
827 /*80*/ { "", TRUE
, BYTE
, op2(I
, E
), (char *)db_Grp1
},
828 /*81*/ { "", TRUE
, LONG
, op2(I
, E
), (char *)db_Grp1
},
829 /*82*/ { "", TRUE
, BYTE
, op2(Is
,E
), (char *)db_Grp1
},
830 /*83*/ { "", TRUE
, LONG
, op2(Ibs
,E
), (char *)db_Grp1
},
831 /*84*/ { "test", TRUE
, BYTE
, op2(R
, E
), 0 },
832 /*85*/ { "test", TRUE
, LONG
, op2(R
, E
), 0 },
833 /*86*/ { "xchg", TRUE
, BYTE
, op2(R
, E
), 0 },
834 /*87*/ { "xchg", TRUE
, LONG
, op2(R
, E
), 0 },
836 /*88*/ { "mov", TRUE
, BYTE
, op2(R
, E
), 0 },
837 /*89*/ { "mov", TRUE
, LONG
, op2(R
, E
), 0 },
838 /*8a*/ { "mov", TRUE
, BYTE
, op2(E
, R
), 0 },
839 /*8b*/ { "mov", TRUE
, LONG
, op2(E
, R
), 0 },
840 /*8c*/ { "mov", TRUE
, NONE
, op2(S
, Ew
), 0 },
841 /*8d*/ { "lea", TRUE
, LONG
, op2(E
, R
), 0 },
842 /*8e*/ { "mov", TRUE
, NONE
, op2(Ew
, S
), 0 },
843 /*8f*/ { "pop", TRUE
, LONG
, op1(E
), 0 },
845 /*90*/ { "nop", FALSE
, NONE
, 0, 0 },
846 /*91*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
847 /*92*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
848 /*93*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
849 /*94*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
850 /*95*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
851 /*96*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
852 /*97*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
854 /*98*/ { "cbw", FALSE
, SDEP
, 0, "cwde" }, /* cbw/cwde */
855 /*99*/ { "cwd", FALSE
, SDEP
, 0, "cdq" }, /* cwd/cdq */
856 /*9a*/ { "lcall", FALSE
, NONE
, op1(OS
), 0 },
857 /*9b*/ { "wait", FALSE
, NONE
, 0, 0 },
858 /*9c*/ { "pushf", FALSE
, LONG
, 0, 0 },
859 /*9d*/ { "popf", FALSE
, LONG
, 0, 0 },
860 /*9e*/ { "sahf", FALSE
, NONE
, 0, 0 },
861 /*9f*/ { "lahf", FALSE
, NONE
, 0, 0 },
863 /*a0*/ { "mov", FALSE
, BYTE
, op2(O
, A
), 0 },
864 /*a1*/ { "mov", FALSE
, LONG
, op2(O
, A
), 0 },
865 /*a2*/ { "mov", FALSE
, BYTE
, op2(A
, O
), 0 },
866 /*a3*/ { "mov", FALSE
, LONG
, op2(A
, O
), 0 },
867 /*a4*/ { "movs", FALSE
, BYTE
, op2(SI
,DI
), 0 },
868 /*a5*/ { "movs", FALSE
, LONG
, op2(SI
,DI
), 0 },
869 /*a6*/ { "cmps", FALSE
, BYTE
, op2(SI
,DI
), 0 },
870 /*a7*/ { "cmps", FALSE
, LONG
, op2(SI
,DI
), 0 },
872 /*a8*/ { "test", FALSE
, BYTE
, op2(I
, A
), 0 },
873 /*a9*/ { "test", FALSE
, LONG
, op2(I
, A
), 0 },
874 /*aa*/ { "stos", FALSE
, BYTE
, op1(DI
), 0 },
875 /*ab*/ { "stos", FALSE
, LONG
, op1(DI
), 0 },
876 /*ac*/ { "lods", FALSE
, BYTE
, op1(SI
), 0 },
877 /*ad*/ { "lods", FALSE
, LONG
, op1(SI
), 0 },
878 /*ae*/ { "scas", FALSE
, BYTE
, op1(SI
), 0 },
879 /*af*/ { "scas", FALSE
, LONG
, op1(SI
), 0 },
881 /*b0*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
882 /*b1*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
883 /*b2*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
884 /*b3*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
885 /*b4*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
886 /*b5*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
887 /*b6*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
888 /*b7*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
890 /*b8*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
891 /*b9*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
892 /*ba*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
893 /*bb*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
894 /*bc*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
895 /*bd*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
896 /*be*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
897 /*bf*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
899 /*c0*/ { "", TRUE
, BYTE
, op2(Ib
, E
), (char *)db_Grp2
},
900 /*c1*/ { "", TRUE
, LONG
, op2(Ib
, E
), (char *)db_Grp2
},
901 /*c2*/ { "ret", FALSE
, NONE
, op1(Iw
), 0 },
902 /*c3*/ { "ret", FALSE
, NONE
, 0, 0 },
903 /*c4*/ { "les", TRUE
, LONG
, op2(E
, R
), 0 },
904 /*c5*/ { "lds", TRUE
, LONG
, op2(E
, R
), 0 },
905 /*c6*/ { "mov", TRUE
, BYTE
, op2(I
, E
), 0 },
906 /*c7*/ { "mov", TRUE
, LONG
, op2(I
, E
), 0 },
908 /*c8*/ { "enter", FALSE
, NONE
, op2(Ib
, Iw
), 0 },
909 /*c9*/ { "leave", FALSE
, NONE
, 0, 0 },
910 /*ca*/ { "lret", FALSE
, NONE
, op1(Iw
), 0 },
911 /*cb*/ { "lret", FALSE
, NONE
, 0, 0 },
912 /*cc*/ { "int", FALSE
, NONE
, op1(o3
), 0 },
913 /*cd*/ { "int", FALSE
, NONE
, op1(Ib
), 0 },
914 /*ce*/ { "into", FALSE
, NONE
, 0, 0 },
915 /*cf*/ { "iret", FALSE
, NONE
, 0, 0 },
917 /*d0*/ { "", TRUE
, BYTE
, op2(o1
, E
), (char *)db_Grp2
},
918 /*d1*/ { "", TRUE
, LONG
, op2(o1
, E
), (char *)db_Grp2
},
919 /*d2*/ { "", TRUE
, BYTE
, op2(CL
, E
), (char *)db_Grp2
},
920 /*d3*/ { "", TRUE
, LONG
, op2(CL
, E
), (char *)db_Grp2
},
921 /*d4*/ { "aam", TRUE
, NONE
, 0, 0 },
922 /*d5*/ { "aad", TRUE
, NONE
, 0, 0 },
923 /*d6*/ { "", FALSE
, NONE
, 0, 0 },
924 /*d7*/ { "xlat", FALSE
, BYTE
, op1(BX
), 0 },
926 /*d8*/ { "", TRUE
, NONE
, 0, (char *)db_Esc8
},
927 /*d9*/ { "", TRUE
, NONE
, 0, (char *)db_Esc9
},
928 /*da*/ { "", TRUE
, NONE
, 0, (char *)db_Esca
},
929 /*db*/ { "", TRUE
, NONE
, 0, (char *)db_Escb
},
930 /*dc*/ { "", TRUE
, NONE
, 0, (char *)db_Escc
},
931 /*dd*/ { "", TRUE
, NONE
, 0, (char *)db_Escd
},
932 /*de*/ { "", TRUE
, NONE
, 0, (char *)db_Esce
},
933 /*df*/ { "", TRUE
, NONE
, 0, (char *)db_Escf
},
935 /*e0*/ { "loopne",FALSE
, NONE
, op1(Db
), 0 },
936 /*e1*/ { "loope", FALSE
, NONE
, op1(Db
), 0 },
937 /*e2*/ { "loop", FALSE
, NONE
, op1(Db
), 0 },
938 /*e3*/ { "jcxz", FALSE
, SDEP
, op1(Db
), "jecxz" },
939 /*e4*/ { "in", FALSE
, BYTE
, op2(Ib
, A
), 0 },
940 /*e5*/ { "in", FALSE
, LONG
, op2(Ib
, A
) , 0 },
941 /*e6*/ { "out", FALSE
, BYTE
, op2(A
, Ib
), 0 },
942 /*e7*/ { "out", FALSE
, LONG
, op2(A
, Ib
) , 0 },
944 /*e8*/ { "call", FALSE
, NONE
, op1(Dl
), 0 },
945 /*e9*/ { "jmp", FALSE
, NONE
, op1(Dl
), 0 },
946 /*ea*/ { "ljmp", FALSE
, NONE
, op1(OS
), 0 },
947 /*eb*/ { "jmp", FALSE
, NONE
, op1(Db
), 0 },
948 /*ec*/ { "in", FALSE
, BYTE
, op2(DX
, A
), 0 },
949 /*ed*/ { "in", FALSE
, LONG
, op2(DX
, A
) , 0 },
950 /*ee*/ { "out", FALSE
, BYTE
, op2(A
, DX
), 0 },
951 /*ef*/ { "out", FALSE
, LONG
, op2(A
, DX
) , 0 },
953 /*f0*/ { "", FALSE
, NONE
, 0, 0 },
954 /*f1*/ { "", FALSE
, NONE
, 0, 0 },
955 /*f2*/ { "", FALSE
, NONE
, 0, 0 },
956 /*f3*/ { "", FALSE
, NONE
, 0, 0 },
957 /*f4*/ { "hlt", FALSE
, NONE
, 0, 0 },
958 /*f5*/ { "cmc", FALSE
, NONE
, 0, 0 },
959 /*f6*/ { "", TRUE
, BYTE
, 0, (char *)db_Grp3
},
960 /*f7*/ { "", TRUE
, LONG
, 0, (char *)db_Grp3
},
962 /*f8*/ { "clc", FALSE
, NONE
, 0, 0 },
963 /*f9*/ { "stc", FALSE
, NONE
, 0, 0 },
964 /*fa*/ { "cli", FALSE
, NONE
, 0, 0 },
965 /*fb*/ { "sti", FALSE
, NONE
, 0, 0 },
966 /*fc*/ { "cld", FALSE
, NONE
, 0, 0 },
967 /*fd*/ { "std", FALSE
, NONE
, 0, 0 },
968 /*fe*/ { "", TRUE
, NONE
, 0, (char *)db_Grp4
},
969 /*ff*/ { "", TRUE
, NONE
, 0, (char *)db_Grp5
},
972 struct inst db_bad_inst
=
973 { "???", FALSE
, NONE
, 0, 0 }
976 #define f_mod(byte) ((byte)>>6)
977 #define f_reg(byte) (((byte)>>3)&0x7)
978 #define f_rm(byte) ((byte)&0x7)
980 #define sib_ss(byte) ((byte)>>6)
981 #define sib_index(byte) (((byte)>>3)&0x7)
982 #define sib_base(byte) ((byte)&0x7)
984 char * db_index_reg_16
[8] = {
995 char * db_reg
[3][8] = {
996 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
997 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
998 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
1001 char * db_seg_reg
[8] = {
1002 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
1006 * lengths for size attributes
1008 int db_lengths
[] = {
1018 #define get_value_inc(result, loc, size, is_signed, task) \
1019 result = db_get_task_value((loc), (size), (is_signed), (task)); \
1023 * Read address at location and return updated location.
1030 struct i_addr
*addrp
, /* out */
1033 int mod
, rm
, sib
, index
, ss
, disp
;
1035 mod
= f_mod(regmodrm
);
1036 rm
= f_rm(regmodrm
);
1039 addrp
->is_reg
= TRUE
;
1043 addrp
->is_reg
= FALSE
;
1052 get_value_inc(disp
, loc
, 2, TRUE
, task
);
1058 addrp
->base
= db_index_reg_16
[rm
];
1062 get_value_inc(disp
, loc
, 1, TRUE
, task
);
1064 addrp
->base
= db_index_reg_16
[rm
];
1067 get_value_inc(disp
, loc
, 2, TRUE
, task
);
1069 addrp
->base
= db_index_reg_16
[rm
];
1074 if (mod
!= 3 && rm
== 4) {
1075 get_value_inc(sib
, loc
, 1, FALSE
, task
);
1077 index
= sib_index(sib
);
1079 addrp
->index
= db_reg
[LONG
][index
];
1080 addrp
->ss
= sib_ss(sib
);
1086 get_value_inc(addrp
->disp
, loc
, 4, FALSE
, task
);
1091 addrp
->base
= db_reg
[LONG
][rm
];
1096 get_value_inc(disp
, loc
, 1, TRUE
, task
);
1098 addrp
->base
= db_reg
[LONG
][rm
];
1102 get_value_inc(disp
, loc
, 4, FALSE
, task
);
1104 addrp
->base
= db_reg
[LONG
][rm
];
1115 struct i_addr
*addrp
,
1118 if (addrp
->is_reg
) {
1119 db_printf("%s", db_reg
[size
][addrp
->disp
]);
1124 db_printf("%s:", seg
);
1127 if (addrp
->base
!= 0 || addrp
->index
!= 0) {
1128 db_printf("%#n", addrp
->disp
);
1131 db_printf("%s", addrp
->base
);
1133 db_printf(",%s,%d", addrp
->index
, 1<<addrp
->ss
);
1136 db_task_printsym((db_addr_t
)addrp
->disp
, DB_STGY_ANY
, task
);
1140 * Disassemble floating-point ("escape") instruction
1141 * and return updated location.
1155 struct i_addr address
;
1158 get_value_inc(regmodrm
, loc
, 1, FALSE
, task
);
1159 fp
= &db_Esc_inst
[inst
- 0xd8][f_reg(regmodrm
)];
1160 mod
= f_mod(regmodrm
);
1163 * Normal address modes.
1165 loc
= db_read_address(loc
, short_addr
, regmodrm
, &address
, task
);
1166 db_printf(fp
->f_name
);
1167 switch(fp
->f_size
) {
1190 db_print_address(seg
, BYTE
, &address
, task
);
1194 * 'reg-reg' - special formats
1196 switch (fp
->f_rrmode
) {
1198 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1199 db_printf("%s\t%%st,%%st(%d)",name
,f_rm(regmodrm
));
1202 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1203 db_printf("%s\t%%st(%d),%%st",name
, f_rm(regmodrm
));
1206 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1207 db_printf("%s\t%%st(%d)",name
, f_rm(regmodrm
));
1210 db_printf("%s", ((char **)fp
->f_rrname
)[f_rm(regmodrm
)]);
1213 db_printf("%s\t%%ax",
1214 ((char **)fp
->f_rrname
)[f_rm(regmodrm
)]);
1217 db_printf("<bad instruction>");
1226 * Disassemble instruction at 'loc'. 'altfmt' specifies an
1227 * (optional) alternate format. Return address of start of
1251 struct i_addr address
;
1255 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1272 case 0x66: /* data16 */
1279 short_addr
= !short_addr
;
1303 db_printf("repne ");
1306 db_printf("repe "); /* XXX repe VS rep */
1313 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1317 if (inst
>= 0xd8 && inst
<= 0xdf) {
1318 loc
= db_disasm_esc(loc
, inst
, short_addr
, size
, seg
, task
);
1324 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1325 ip
= db_inst_0f
[inst
>>4];
1334 ip
= &db_inst_table
[inst
];
1336 if (ip
->i_has_modrm
) {
1337 get_value_inc(regmodrm
, loc
, 1, FALSE
, task
);
1338 loc
= db_read_address(loc
, short_addr
, regmodrm
, &address
, task
);
1341 i_name
= ip
->i_name
;
1342 i_size
= ip
->i_size
;
1343 i_mode
= ip
->i_mode
;
1345 if (ip
->i_extra
== (char *)db_Grp1
||
1346 ip
->i_extra
== (char *)db_Grp2
||
1347 ip
->i_extra
== (char *)db_Grp6
||
1348 ip
->i_extra
== (char *)db_Grp7
||
1349 ip
->i_extra
== (char *)db_Grp8
) {
1350 i_name
= ((char **)ip
->i_extra
)[f_reg(regmodrm
)];
1352 else if (ip
->i_extra
== (char *)db_Grp3
) {
1353 ip
= (struct inst
*)ip
->i_extra
;
1354 ip
= &ip
[f_reg(regmodrm
)];
1355 i_name
= ip
->i_name
;
1356 i_mode
= ip
->i_mode
;
1358 else if (ip
->i_extra
== (char *)db_Grp4
||
1359 ip
->i_extra
== (char *)db_Grp5
) {
1360 ip
= (struct inst
*)ip
->i_extra
;
1361 ip
= &ip
[f_reg(regmodrm
)];
1362 i_name
= ip
->i_name
;
1363 i_mode
= ip
->i_mode
;
1364 i_size
= ip
->i_size
;
1367 if (i_size
== SDEP
) {
1371 db_printf(ip
->i_extra
);
1375 if (i_size
!= NONE
) {
1376 if (i_size
== BYTE
) {
1380 else if (i_size
== WORD
) {
1384 else if (size
== WORD
)
1393 i_mode
>>= 8, first
= FALSE
)
1398 switch (i_mode
& 0xFF) {
1401 db_print_address(seg
, size
, &address
, task
);
1406 db_print_address(seg
, size
, &address
, task
);
1410 db_print_address(seg
, WORD
, &address
, task
);
1414 db_print_address(seg
, BYTE
, &address
, task
);
1418 db_printf("%s", db_reg
[size
][f_reg(regmodrm
)]);
1422 db_printf("%s", db_reg
[WORD
][f_reg(regmodrm
)]);
1426 db_printf("%s", db_reg
[size
][f_rm(inst
)]);
1430 db_printf("%s", db_seg_reg
[f_reg(regmodrm
)]);
1434 db_printf("%s", db_seg_reg
[f_reg(inst
)]);
1438 db_printf("%s", db_reg
[size
][0]); /* acc */
1443 db_printf("%s:", seg
);
1444 db_printf("(%s)", short_addr
? "%bx" : "%ebx");
1457 db_printf("%s:", seg
);
1458 db_printf("(%s)", short_addr
? "%si" : "%esi");
1462 db_printf("%%es:(%s)", short_addr
? "%di" : "%edi");
1466 db_printf("%%cr%d", f_reg(regmodrm
));
1470 db_printf("%%dr%d", f_reg(regmodrm
));
1474 db_printf("%%tr%d", f_reg(regmodrm
));
1478 len
= db_lengths
[size
];
1479 get_value_inc(imm
, loc
, len
, FALSE
, task
);/* unsigned */
1480 db_printf("$%#n", imm
);
1484 len
= db_lengths
[size
];
1485 get_value_inc(imm
, loc
, len
, TRUE
, task
); /* signed */
1486 db_printf("$%#r", imm
);
1490 get_value_inc(imm
, loc
, 1, FALSE
, task
); /* unsigned */
1491 db_printf("$%#n", imm
);
1495 get_value_inc(imm
, loc
, 1, TRUE
, task
); /* signed */
1496 db_printf("$%#r", imm
);
1500 get_value_inc(imm
, loc
, 2, FALSE
, task
); /* unsigned */
1501 db_printf("$%#n", imm
);
1505 get_value_inc(imm
, loc
, 4, FALSE
, task
);
1506 db_printf("$%#n", imm
);
1511 get_value_inc(displ
, loc
, 2, TRUE
, task
);
1514 get_value_inc(displ
, loc
, 4, TRUE
, task
);
1517 db_printf("%s:%#r",seg
, displ
);
1519 db_task_printsym((db_addr_t
)displ
, DB_STGY_ANY
, task
);
1523 get_value_inc(displ
, loc
, 1, TRUE
, task
);
1525 /* offset only affects low 16 bits */
1526 displ
= (loc
& 0xffff0000)
1527 | ((loc
+ displ
) & 0xffff);
1530 displ
= displ
+ loc
;
1531 db_task_printsym((db_addr_t
)displ
,DB_STGY_ANY
,task
);
1532 if (db_line_at_pc(0, &filename
, &linenum
, displ
)) {
1533 db_printf(" [%s", filename
);
1535 db_printf(":%d", linenum
);
1542 get_value_inc(displ
, loc
, 2, TRUE
, task
);
1543 /* offset only affects low 16 bits */
1544 displ
= (loc
& 0xffff0000)
1545 | ((loc
+ displ
) & 0xffff);
1548 get_value_inc(displ
, loc
, 4, TRUE
, task
);
1549 displ
= displ
+ loc
;
1551 db_task_printsym((db_addr_t
)displ
, DB_STGY_ANY
, task
);
1552 if (db_line_at_pc(0, &filename
, &linenum
, displ
)) {
1553 db_printf(" [%s", filename
);
1555 db_printf(":%d", linenum
);
1570 get_value_inc(imm
, loc
, 2, FALSE
, task
); /* offset */
1573 get_value_inc(imm
, loc
, 4, FALSE
, task
); /* offset */
1575 get_value_inc(imm2
, loc
, 2, FALSE
, task
); /* segment */
1576 db_printf("$%#n,%#n", imm2
, imm
);
1581 if (altfmt
== 0 && !db_disasm_16
) {
1582 if (inst
== 0xe9 || inst
== 0xeb) { /* jmp, Dl or Db */
1584 * GAS pads to longword boundary after unconditional jumps.
1586 while (loc
& (4-1)) {
1587 get_value_inc(inst
, loc
, 0, FALSE
, task
);
1588 if (inst
!= 0x90) /* nop */
1599 * Classify instructions by whether they read or write memory.
1602 #define DBLS_LOAD 0x01 /* instruction reads from memory */
1603 #define DBLS_STORE 0x02 /* instruction writes to memory */
1605 #define DBLS_MODRM 0x10 /* instruction uses mod r/m byte */
1606 #define DBLS_SECOND 0x20 /* instruction does two operations */
1607 #define DBLS_ESCAPE 0x40 /* escape to two-byte opcodes */
1608 #define DBLS_SWREG 0x80 /* need to switch on reg bits of mod r/m */
1610 #define DBLS_MODS 0xf0
1611 #define DBLS_LMASK (DBLS_MODS|DBLS_LOAD)
1612 #define DBLS_SMASK (DBLS_MODS|DBLS_STORE)
1614 char db_ldstrtab
[] = {
1615 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1616 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x40,
1617 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1618 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1619 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1620 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1621 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1622 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1626 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1627 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1628 0x02, 0x01, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
1629 0x02, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
1630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1633 0x12, 0x12, 0x00, 0x12, 0x11, 0x11, 0x13, 0x13,
1634 0x12, 0x12, 0x11, 0x11, 0x12, 0x00, 0x11, 0x03,
1635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00, 0x00,
1637 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x21, 0x21,
1638 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
1639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1642 0x13, 0x13, 0x00, 0x00, 0x01, 0x01, 0x12, 0x12,
1643 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x01,
1645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
1649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
1652 unsigned char db_ldstrtab0f
[] = {
1653 0x80, 0x80, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1673 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
1674 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
1675 0x02, 0x01, 0x00, 0x11, 0x13, 0x13, 0x00, 0x00,
1676 0x02, 0x01, 0x12, 0x13, 0x13, 0x13, 0x00, 0x11,
1677 0x00, 0x00, 0x01, 0x13, 0x01, 0x01, 0x11, 0x11,
1678 0x00, 0x00, 0x80, 0x13, 0x13, 0x13, 0x11, 0x11,
1680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 int db_inst_swreg(boolean_t
, unsigned long, unsigned char);
1693 * Given four bytes of instruction (stored as an int, not an
1694 * array of characters), compute if the instruction reads
1701 unsigned char insb
, bits
;
1705 bits
= db_ldstrtab
[insb
];
1706 if (!(bits
& DBLS_LOAD
))
1709 switch (bits
& DBLS_MODS
) {
1714 return ((insb
& 0xc0) != 0xc0);
1715 case DBLS_SECOND
|DBLS_MODRM
:
1717 return ((insb
& 0xc0) != 0xc0 ? 2 : 0);
1723 bits
= db_ldstrtab0f
[insb
];
1726 return (db_inst_swreg(TRUE
, insw
, insb
));
1728 panic ("db_inst_load: unknown mod bits");
1734 * Given four bytes of instruction (stored as an int, not an
1735 * array of characters), compute if the instruction writes
1742 unsigned char insb
, bits
;
1746 bits
= db_ldstrtab
[insb
];
1747 if (!(bits
& DBLS_STORE
))
1750 switch (bits
& DBLS_MODS
) {
1755 return ((insb
& 0xc0) != 0xc0);
1756 case DBLS_SECOND
|DBLS_MODRM
:
1758 return ((insb
& 0xc0) != 0xc0 ? 2 : 0);
1764 bits
= db_ldstrtab0f
[insb
];
1767 return (db_inst_swreg(FALSE
, insw
, insb
));
1769 panic ("db_inst_store: unknown mod bits");
1775 * Parse a mod r/m byte to see if extended opcode reads
1784 unsigned char modrm
= insw
& 0xff;
1788 switch (modrm
& 0x38) {
1793 return ((modrm
& 0xc0) != 0xc0);
1797 switch (modrm
& 0x38) {
1802 return ((modrm
& 0xc0) != 0xc0 ? 2 : 0);
1805 return ((modrm
& 0xc0) != 0xc0);
1810 return ((modrm
& 0xc0) != 0xc0);
1811 switch (modrm
& 0x38) {
1815 return ((modrm
& 0xc0) != 0xc0);