]>
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 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
29 * Revision 1.1.1.1 1998/09/22 21:05:36 wsanchez
30 * Import of Mac OS X kernel (~semeria)
32 * Revision 1.1.1.1 1998/03/07 02:25:37 wsanchez
33 * Import of OSF Mach kernel (~mburg)
35 * Revision 1.2.8.3 1996/07/31 09:43:35 paire
36 * Merged with nmk20b7_shared (1.2.11.1)
39 * Revision 1.2.11.1 1996/05/14 13:49:36 paire
40 * Added support for new cmpxchg8b, cpuid, rdtsc, rdwmr, rsm and wrmsr
41 * Pentium instructions
44 * Revision 1.2.8.2 1994/09/23 01:50:45 ezf
45 * change marker to not FREE
46 * [1994/09/22 21:21:17 ezf]
48 * Revision 1.2.8.1 1994/09/16 15:26:28 emcmanus
49 * Only skip over GAS-inserted NOPs after branches if they are really
50 * NOPs; this depends at least on assembler options.
51 * [1994/09/16 15:26:03 emcmanus]
53 * Revision 1.2.6.3 1994/02/19 15:40:34 bolinger
54 * For load/store counting, mark all varieties of "call" as writing
56 * [1994/02/15 20:25:18 bolinger]
58 * Revision 1.2.6.2 1994/02/14 21:46:49 dwm
60 * [1994/02/14 21:46:14 dwm]
62 * Revision 1.2.6.1 1994/02/12 23:26:05 bolinger
63 * Implement load/store counting for ddb "until" command.
64 * [1994/02/12 03:34:55 bolinger]
66 * Revision 1.2.2.3 1993/08/09 19:39:21 dswartz
67 * Add ANSI prototypes - CR#9523
68 * [1993/08/06 17:44:13 dswartz]
70 * Revision 1.2.2.2 1993/06/09 02:27:29 gm
71 * Added to OSF/1 R1.3 from NMK15.0.
72 * [1993/06/02 21:03:54 jeffc]
74 * Revision 1.2 1993/04/19 16:12:57 devrcs
75 * Print file names and lineno on branch instructions.
79 * Revision 1.1 1992/09/30 02:02:19 robert
86 * Revision 2.5.3.1 92/03/03 16:14:27 jeffreyh
87 * Pick up changes from TRUNK
88 * [92/02/26 11:05:06 jeffreyh]
90 * Revision 2.6 92/01/03 20:05:00 dbg
91 * Add a switch to disassemble 16-bit code.
92 * Fix spelling of 'lods' opcodes.
95 * Revision 2.5 91/10/09 16:05:58 af
96 * Supported disassemble of non current task by passing task parameter.
99 * Revision 2.4 91/05/14 16:05:04 mrt
100 * Correcting copyright
102 * Revision 2.3 91/02/05 17:11:03 mrt
103 * Changed to new Mach copyright
104 * [91/02/01 17:31:03 mrt]
106 * Revision 2.2 90/08/27 21:55:56 dbg
107 * Fix register operand for move to/from control/test/debug
108 * register instructions. Add i486 instructions.
111 * Import db_sym.h. Print instruction displacements in
112 * current radix (signed). Change calling sequence of
123 * Mach Operating System
124 * Copyright (c) 1991,1990 Carnegie Mellon University
125 * All Rights Reserved.
127 * Permission to use, copy, modify and distribute this software and its
128 * documentation is hereby granted, provided that both the copyright
129 * notice and this permission notice appear in all copies of the
130 * software, derivative works or modified versions, and any portions
131 * thereof, and that both notices appear in supporting documentation.
133 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
134 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
135 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
137 * Carnegie Mellon requests users of this software to return to
139 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
140 * School of Computer Science
141 * Carnegie Mellon University
142 * Pittsburgh PA 15213-3890
144 * any improvements or extensions that they make and grant Carnegie Mellon
145 * the rights to redistribute these changes.
151 * Instruction disassembler.
154 #include <mach/boolean.h>
155 #include <machine/db_machdep.h>
157 #include <ddb/db_access.h>
158 #include <ddb/db_sym.h>
159 #include <ddb/db_output.h>
161 #include <kern/task.h>
162 #include <kern/misc_protos.h>
165 int is_reg
; /* if reg, reg number is in 'disp' */
174 extern db_addr_t
db_read_address(
178 struct i_addr
* addrp
,
180 extern void db_print_address(
183 struct i_addr
*addrp
,
185 extern db_addr_t
db_disasm_esc(
194 * Switch to disassemble 16-bit code.
196 boolean_t db_disasm_16
= FALSE
;
214 #define E 1 /* general effective address */
215 #define Eind 2 /* indirect address (jump, call) */
216 #define Ew 3 /* address, word size */
217 #define Eb 4 /* address, byte size */
218 #define R 5 /* register, in 'reg' field */
219 #define Rw 6 /* word register, in 'reg' field */
220 #define Ri 7 /* register in instruction */
221 #define S 8 /* segment reg, in 'reg' field */
222 #define Si 9 /* segment reg, in instruction */
223 #define A 10 /* accumulator */
224 #define BX 11 /* (bx) */
225 #define CL 12 /* cl, for shifts */
226 #define DX 13 /* dx, for IO */
227 #define SI 14 /* si */
228 #define DI 15 /* di */
229 #define CR 16 /* control register */
230 #define DR 17 /* debug register */
231 #define TR 18 /* test register */
232 #define I 19 /* immediate, unsigned */
233 #define Is 20 /* immediate, signed */
234 #define Ib 21 /* byte immediate, unsigned */
235 #define Ibs 22 /* byte immediate, signed */
236 #define Iw 23 /* word immediate, unsigned */
237 #define Il 24 /* long immediate */
238 #define O 25 /* direct address */
239 #define Db 26 /* byte displacement from EIP */
240 #define Dl 27 /* long displacement from EIP */
241 #define o1 28 /* constant 1 */
242 #define o3 29 /* constant 3 */
243 #define OS 30 /* immediate offset/segment */
244 #define ST 31 /* FP stack top */
245 #define STI 32 /* FP stack */
246 #define X 33 /* extended FP op */
247 #define XA 34 /* for 'fstcw %ax' */
250 char * i_name
; /* name */
251 short i_has_modrm
; /* has regmodrm byte */
252 short i_size
; /* operand size */
253 int i_mode
; /* addressing modes */
254 char * i_extra
; /* pointer to extra opcode table */
258 #define op2(x,y) ((x)|((y)<<8))
259 #define op3(x,y,z) ((x)|((y)<<8)|((z)<<16))
262 char * f_name
; /* name for memory instruction */
263 int f_size
; /* size for memory instruction */
264 int f_rrmode
; /* mode for rr instruction */
265 char * f_rrname
; /* name for rr instruction
266 (or pointer to table) */
302 struct inst db_inst_0f0x
[] = {
303 /*00*/ { "", TRUE
, NONE
, op1(Ew
), (char *)db_Grp6
},
304 /*01*/ { "", TRUE
, NONE
, op1(Ew
), (char *)db_Grp7
},
305 /*02*/ { "lar", TRUE
, LONG
, op2(E
,R
), 0 },
306 /*03*/ { "lsl", TRUE
, LONG
, op2(E
,R
), 0 },
307 /*04*/ { "", FALSE
, NONE
, 0, 0 },
308 /*05*/ { "", FALSE
, NONE
, 0, 0 },
309 /*06*/ { "clts", FALSE
, NONE
, 0, 0 },
310 /*07*/ { "", FALSE
, NONE
, 0, 0 },
312 /*08*/ { "invd", FALSE
, NONE
, 0, 0 },
313 /*09*/ { "wbinvd",FALSE
, NONE
, 0, 0 },
314 /*0a*/ { "", FALSE
, NONE
, 0, 0 },
315 /*0b*/ { "", FALSE
, NONE
, 0, 0 },
316 /*0c*/ { "", FALSE
, NONE
, 0, 0 },
317 /*0d*/ { "", FALSE
, NONE
, 0, 0 },
318 /*0e*/ { "", FALSE
, NONE
, 0, 0 },
319 /*0f*/ { "", FALSE
, NONE
, 0, 0 },
322 struct inst db_inst_0f2x
[] = {
323 /*20*/ { "mov", TRUE
, LONG
, op2(CR
,E
), 0 }, /* use E for reg */
324 /*21*/ { "mov", TRUE
, LONG
, op2(DR
,E
), 0 }, /* since mod == 11 */
325 /*22*/ { "mov", TRUE
, LONG
, op2(E
,CR
), 0 },
326 /*23*/ { "mov", TRUE
, LONG
, op2(E
,DR
), 0 },
327 /*24*/ { "mov", TRUE
, LONG
, op2(TR
,E
), 0 },
328 /*25*/ { "", FALSE
, NONE
, 0, 0 },
329 /*26*/ { "mov", TRUE
, LONG
, op2(E
,TR
), 0 },
330 /*27*/ { "", FALSE
, NONE
, 0, 0 },
332 /*28*/ { "", FALSE
, NONE
, 0, 0 },
333 /*29*/ { "", FALSE
, NONE
, 0, 0 },
334 /*2a*/ { "", FALSE
, NONE
, 0, 0 },
335 /*2b*/ { "", FALSE
, NONE
, 0, 0 },
336 /*2c*/ { "", FALSE
, NONE
, 0, 0 },
337 /*2d*/ { "", FALSE
, NONE
, 0, 0 },
338 /*2e*/ { "", FALSE
, NONE
, 0, 0 },
339 /*2f*/ { "", FALSE
, NONE
, 0, 0 },
341 struct inst db_inst_0f3x
[] = {
342 /*30*/ { "rdtsc", FALSE
, NONE
, 0, 0 },
343 /*31*/ { "rdmsr", FALSE
, NONE
, 0, 0 },
344 /*32*/ { "wrmsr", FALSE
, NONE
, 0, 0 },
345 /*33*/ { "", FALSE
, NONE
, 0, 0 },
346 /*34*/ { "", FALSE
, NONE
, 0, 0 },
347 /*35*/ { "", FALSE
, NONE
, 0, 0 },
348 /*36*/ { "", FALSE
, NONE
, 0, 0 },
349 /*37*/ { "", FALSE
, NONE
, 0, 0 },
351 /*38*/ { "", FALSE
, NONE
, 0, 0 },
352 /*39*/ { "", FALSE
, NONE
, 0, 0 },
353 /*3a*/ { "", FALSE
, NONE
, 0, 0 },
354 /*3b*/ { "", FALSE
, NONE
, 0, 0 },
355 /*3c*/ { "", FALSE
, NONE
, 0, 0 },
356 /*3d*/ { "", FALSE
, NONE
, 0, 0 },
357 /*3e*/ { "", FALSE
, NONE
, 0, 0 },
358 /*3f*/ { "", FALSE
, NONE
, 0, 0 },
361 struct inst db_inst_0f8x
[] = {
362 /*80*/ { "jo", FALSE
, NONE
, op1(Dl
), 0 },
363 /*81*/ { "jno", FALSE
, NONE
, op1(Dl
), 0 },
364 /*82*/ { "jb", FALSE
, NONE
, op1(Dl
), 0 },
365 /*83*/ { "jnb", FALSE
, NONE
, op1(Dl
), 0 },
366 /*84*/ { "jz", FALSE
, NONE
, op1(Dl
), 0 },
367 /*85*/ { "jnz", FALSE
, NONE
, op1(Dl
), 0 },
368 /*86*/ { "jbe", FALSE
, NONE
, op1(Dl
), 0 },
369 /*87*/ { "jnbe", FALSE
, NONE
, op1(Dl
), 0 },
371 /*88*/ { "js", FALSE
, NONE
, op1(Dl
), 0 },
372 /*89*/ { "jns", FALSE
, NONE
, op1(Dl
), 0 },
373 /*8a*/ { "jp", FALSE
, NONE
, op1(Dl
), 0 },
374 /*8b*/ { "jnp", FALSE
, NONE
, op1(Dl
), 0 },
375 /*8c*/ { "jl", FALSE
, NONE
, op1(Dl
), 0 },
376 /*8d*/ { "jnl", FALSE
, NONE
, op1(Dl
), 0 },
377 /*8e*/ { "jle", FALSE
, NONE
, op1(Dl
), 0 },
378 /*8f*/ { "jnle", FALSE
, NONE
, op1(Dl
), 0 },
381 struct inst db_inst_0f9x
[] = {
382 /*90*/ { "seto", TRUE
, NONE
, op1(Eb
), 0 },
383 /*91*/ { "setno", TRUE
, NONE
, op1(Eb
), 0 },
384 /*92*/ { "setb", TRUE
, NONE
, op1(Eb
), 0 },
385 /*93*/ { "setnb", TRUE
, NONE
, op1(Eb
), 0 },
386 /*94*/ { "setz", TRUE
, NONE
, op1(Eb
), 0 },
387 /*95*/ { "setnz", TRUE
, NONE
, op1(Eb
), 0 },
388 /*96*/ { "setbe", TRUE
, NONE
, op1(Eb
), 0 },
389 /*97*/ { "setnbe",TRUE
, NONE
, op1(Eb
), 0 },
391 /*98*/ { "sets", TRUE
, NONE
, op1(Eb
), 0 },
392 /*99*/ { "setns", TRUE
, NONE
, op1(Eb
), 0 },
393 /*9a*/ { "setp", TRUE
, NONE
, op1(Eb
), 0 },
394 /*9b*/ { "setnp", TRUE
, NONE
, op1(Eb
), 0 },
395 /*9c*/ { "setl", TRUE
, NONE
, op1(Eb
), 0 },
396 /*9d*/ { "setnl", TRUE
, NONE
, op1(Eb
), 0 },
397 /*9e*/ { "setle", TRUE
, NONE
, op1(Eb
), 0 },
398 /*9f*/ { "setnle",TRUE
, NONE
, op1(Eb
), 0 },
401 struct inst db_inst_0fax
[] = {
402 /*a0*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
403 /*a1*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
404 /*a2*/ { "cpuid", FALSE
, NONE
, 0, 0 },
405 /*a3*/ { "bt", TRUE
, LONG
, op2(E
,R
), 0 },
406 /*a4*/ { "shld", TRUE
, LONG
, op3(Ib
,E
,R
), 0 },
407 /*a5*/ { "shld", TRUE
, LONG
, op3(CL
,E
,R
), 0 },
408 /*a6*/ { "", FALSE
, NONE
, 0, 0 },
409 /*a7*/ { "", FALSE
, NONE
, 0, 0 },
411 /*a8*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
412 /*a9*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
413 /*aa*/ { "rsm", FALSE
, NONE
, 0, 0 },
414 /*ab*/ { "bts", TRUE
, LONG
, op2(E
,R
), 0 },
415 /*ac*/ { "shrd", TRUE
, LONG
, op3(Ib
,E
,R
), 0 },
416 /*ad*/ { "shrd", TRUE
, LONG
, op3(CL
,E
,R
), 0 },
417 /*a6*/ { "", FALSE
, NONE
, 0, 0 },
418 /*a7*/ { "imul", TRUE
, LONG
, op2(E
,R
), 0 },
421 struct inst db_inst_0fbx
[] = {
422 /*b0*/ { "", FALSE
, NONE
, 0, 0 },
423 /*b1*/ { "", FALSE
, NONE
, 0, 0 },
424 /*b2*/ { "lss", TRUE
, LONG
, op2(E
, R
), 0 },
425 /*b3*/ { "bts", TRUE
, LONG
, op2(R
, E
), 0 },
426 /*b4*/ { "lfs", TRUE
, LONG
, op2(E
, R
), 0 },
427 /*b5*/ { "lgs", TRUE
, LONG
, op2(E
, R
), 0 },
428 /*b6*/ { "movzb", TRUE
, LONG
, op2(E
, R
), 0 },
429 /*b7*/ { "movzw", TRUE
, LONG
, op2(E
, R
), 0 },
431 /*b8*/ { "", FALSE
, NONE
, 0, 0 },
432 /*b9*/ { "", FALSE
, NONE
, 0, 0 },
433 /*ba*/ { "", TRUE
, LONG
, op2(Is
, E
), (char *)db_Grp8
},
434 /*bb*/ { "btc", TRUE
, LONG
, op2(R
, E
), 0 },
435 /*bc*/ { "bsf", TRUE
, LONG
, op2(E
, R
), 0 },
436 /*bd*/ { "bsr", TRUE
, LONG
, op2(E
, R
), 0 },
437 /*be*/ { "movsb", TRUE
, LONG
, op2(E
, R
), 0 },
438 /*bf*/ { "movsw", TRUE
, LONG
, op2(E
, R
), 0 },
441 struct inst db_inst_0fcx
[] = {
442 /*c0*/ { "xadd", TRUE
, BYTE
, op2(R
, E
), 0 },
443 /*c1*/ { "xadd", TRUE
, LONG
, op2(R
, E
), 0 },
444 /*c2*/ { "", FALSE
, NONE
, 0, 0 },
445 /*c3*/ { "", FALSE
, NONE
, 0, 0 },
446 /*c4*/ { "", FALSE
, NONE
, 0, 0 },
447 /*c5*/ { "", FALSE
, NONE
, 0, 0 },
448 /*c6*/ { "", FALSE
, NONE
, 0, 0 },
449 /*c7*/ { "cmpxchg8b", FALSE
, NONE
, op1(E
), 0 },
450 /*c8*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
451 /*c9*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
452 /*ca*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
453 /*cb*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
454 /*cc*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
455 /*cd*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
456 /*ce*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
457 /*cf*/ { "bswap", FALSE
, LONG
, op1(Ri
), 0 },
460 struct inst db_inst_0fdx
[] = {
461 /*c0*/ { "cmpxchg",TRUE
, BYTE
, op2(R
, E
), 0 },
462 /*c1*/ { "cmpxchg",TRUE
, LONG
, op2(R
, E
), 0 },
463 /*c2*/ { "", FALSE
, NONE
, 0, 0 },
464 /*c3*/ { "", FALSE
, NONE
, 0, 0 },
465 /*c4*/ { "", FALSE
, NONE
, 0, 0 },
466 /*c5*/ { "", FALSE
, NONE
, 0, 0 },
467 /*c6*/ { "", FALSE
, NONE
, 0, 0 },
468 /*c7*/ { "", FALSE
, NONE
, 0, 0 },
469 /*c8*/ { "", FALSE
, NONE
, 0, 0 },
470 /*c9*/ { "", FALSE
, NONE
, 0, 0 },
471 /*ca*/ { "", FALSE
, NONE
, 0, 0 },
472 /*cb*/ { "", FALSE
, NONE
, 0, 0 },
473 /*cc*/ { "", FALSE
, NONE
, 0, 0 },
474 /*cd*/ { "", FALSE
, NONE
, 0, 0 },
475 /*ce*/ { "", FALSE
, NONE
, 0, 0 },
476 /*cf*/ { "", FALSE
, NONE
, 0, 0 },
479 struct inst
*db_inst_0f
[] = {
498 char * db_Esc92
[] = {
499 "fnop", "", "", "", "", "", "", ""
501 char * db_Esc93
[] = {
502 "", "", "", "", "", "", "", ""
504 char * db_Esc94
[] = {
505 "fchs", "fabs", "", "", "ftst", "fxam", "", ""
507 char * db_Esc95
[] = {
508 "fld1", "fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz",""
510 char * db_Esc96
[] = {
511 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp",
514 char * db_Esc97
[] = {
515 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos"
518 char * db_Esca4
[] = {
519 "", "fucompp","", "", "", "", "", ""
522 char * db_Escb4
[] = {
523 "", "", "fnclex","fninit","", "", "", ""
526 char * db_Esce3
[] = {
527 "", "fcompp","", "", "", "", "", ""
530 char * db_Escf4
[] = {
531 "fnstsw","", "", "", "", "", "", ""
534 struct finst db_Esc8
[] = {
535 /*0*/ { "fadd", SNGL
, op2(STI
,ST
), 0 },
536 /*1*/ { "fmul", SNGL
, op2(STI
,ST
), 0 },
537 /*2*/ { "fcom", SNGL
, op2(STI
,ST
), 0 },
538 /*3*/ { "fcomp", SNGL
, op2(STI
,ST
), 0 },
539 /*4*/ { "fsub", SNGL
, op2(STI
,ST
), 0 },
540 /*5*/ { "fsubr", SNGL
, op2(STI
,ST
), 0 },
541 /*6*/ { "fdiv", SNGL
, op2(STI
,ST
), 0 },
542 /*7*/ { "fdivr", SNGL
, op2(STI
,ST
), 0 },
545 struct finst db_Esc9
[] = {
546 /*0*/ { "fld", SNGL
, op1(STI
), 0 },
547 /*1*/ { "", NONE
, op1(STI
), "fxch" },
548 /*2*/ { "fst", SNGL
, op1(X
), (char *)db_Esc92
},
549 /*3*/ { "fstp", SNGL
, op1(X
), (char *)db_Esc93
},
550 /*4*/ { "fldenv", NONE
, op1(X
), (char *)db_Esc94
},
551 /*5*/ { "fldcw", NONE
, op1(X
), (char *)db_Esc95
},
552 /*6*/ { "fnstenv",NONE
, op1(X
), (char *)db_Esc96
},
553 /*7*/ { "fnstcw", NONE
, op1(X
), (char *)db_Esc97
},
556 struct finst db_Esca
[] = {
557 /*0*/ { "fiadd", WORD
, 0, 0 },
558 /*1*/ { "fimul", WORD
, 0, 0 },
559 /*2*/ { "ficom", WORD
, 0, 0 },
560 /*3*/ { "ficomp", WORD
, 0, 0 },
561 /*4*/ { "fisub", WORD
, op1(X
), (char *)db_Esca4
},
562 /*5*/ { "fisubr", WORD
, 0, 0 },
563 /*6*/ { "fidiv", WORD
, 0, 0 },
564 /*7*/ { "fidivr", WORD
, 0, 0 }
567 struct finst db_Escb
[] = {
568 /*0*/ { "fild", WORD
, 0, 0 },
569 /*1*/ { "", NONE
, 0, 0 },
570 /*2*/ { "fist", WORD
, 0, 0 },
571 /*3*/ { "fistp", WORD
, 0, 0 },
572 /*4*/ { "", WORD
, op1(X
), (char *)db_Escb4
},
573 /*5*/ { "fld", EXTR
, 0, 0 },
574 /*6*/ { "", WORD
, 0, 0 },
575 /*7*/ { "fstp", EXTR
, 0, 0 },
578 struct finst db_Escc
[] = {
579 /*0*/ { "fadd", DBLR
, op2(ST
,STI
), 0 },
580 /*1*/ { "fmul", DBLR
, op2(ST
,STI
), 0 },
581 /*2*/ { "fcom", DBLR
, op2(ST
,STI
), 0 },
582 /*3*/ { "fcomp", DBLR
, op2(ST
,STI
), 0 },
583 /*4*/ { "fsub", DBLR
, op2(ST
,STI
), "fsubr" },
584 /*5*/ { "fsubr", DBLR
, op2(ST
,STI
), "fsub" },
585 /*6*/ { "fdiv", DBLR
, op2(ST
,STI
), "fdivr" },
586 /*7*/ { "fdivr", DBLR
, op2(ST
,STI
), "fdiv" },
589 struct finst db_Escd
[] = {
590 /*0*/ { "fld", DBLR
, op1(STI
), "ffree" },
591 /*1*/ { "", NONE
, 0, 0 },
592 /*2*/ { "fst", DBLR
, op1(STI
), 0 },
593 /*3*/ { "fstp", DBLR
, op1(STI
), 0 },
594 /*4*/ { "frstor", NONE
, op1(STI
), "fucom" },
595 /*5*/ { "", NONE
, op1(STI
), "fucomp" },
596 /*6*/ { "fnsave", NONE
, 0, 0 },
597 /*7*/ { "fnstsw", NONE
, 0, 0 },
600 struct finst db_Esce
[] = {
601 /*0*/ { "fiadd", LONG
, op2(ST
,STI
), "faddp" },
602 /*1*/ { "fimul", LONG
, op2(ST
,STI
), "fmulp" },
603 /*2*/ { "ficom", LONG
, 0, 0 },
604 /*3*/ { "ficomp", LONG
, op1(X
), (char *)db_Esce3
},
605 /*4*/ { "fisub", LONG
, op2(ST
,STI
), "fsubrp" },
606 /*5*/ { "fisubr", LONG
, op2(ST
,STI
), "fsubp" },
607 /*6*/ { "fidiv", LONG
, op2(ST
,STI
), "fdivrp" },
608 /*7*/ { "fidivr", LONG
, op2(ST
,STI
), "fdivp" },
611 struct finst db_Escf
[] = {
612 /*0*/ { "fild", LONG
, 0, 0 },
613 /*1*/ { "", LONG
, 0, 0 },
614 /*2*/ { "fist", LONG
, 0, 0 },
615 /*3*/ { "fistp", LONG
, 0, 0 },
616 /*4*/ { "fbld", NONE
, op1(XA
), (char *)db_Escf4
},
617 /*5*/ { "fld", QUAD
, 0, 0 },
618 /*6*/ { "fbstp", NONE
, 0, 0 },
619 /*7*/ { "fstp", QUAD
, 0, 0 },
622 struct finst
*db_Esc_inst
[] = {
623 db_Esc8
, db_Esc9
, db_Esca
, db_Escb
,
624 db_Escc
, db_Escd
, db_Esce
, db_Escf
649 struct inst db_Grp3
[] = {
650 { "test", TRUE
, NONE
, op2(I
,E
), 0 },
651 { "test", TRUE
, NONE
, op2(I
,E
), 0 },
652 { "not", TRUE
, NONE
, op1(E
), 0 },
653 { "neg", TRUE
, NONE
, op1(E
), 0 },
654 { "mul", TRUE
, NONE
, op2(E
,A
), 0 },
655 { "imul", TRUE
, NONE
, op2(E
,A
), 0 },
656 { "div", TRUE
, NONE
, op2(E
,A
), 0 },
657 { "idiv", TRUE
, NONE
, op2(E
,A
), 0 },
660 struct inst db_Grp4
[] = {
661 { "inc", TRUE
, BYTE
, op1(E
), 0 },
662 { "dec", TRUE
, BYTE
, op1(E
), 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 },
668 { "", TRUE
, NONE
, 0, 0 }
671 struct inst db_Grp5
[] = {
672 { "inc", TRUE
, LONG
, op1(E
), 0 },
673 { "dec", TRUE
, LONG
, op1(E
), 0 },
674 { "call", TRUE
, NONE
, op1(Eind
),0 },
675 { "lcall", TRUE
, NONE
, op1(Eind
),0 },
676 { "jmp", TRUE
, NONE
, op1(Eind
),0 },
677 { "ljmp", TRUE
, NONE
, op1(Eind
),0 },
678 { "push", TRUE
, LONG
, op1(E
), 0 },
679 { "", TRUE
, NONE
, 0, 0 }
682 struct inst db_inst_table
[256] = {
683 /*00*/ { "add", TRUE
, BYTE
, op2(R
, E
), 0 },
684 /*01*/ { "add", TRUE
, LONG
, op2(R
, E
), 0 },
685 /*02*/ { "add", TRUE
, BYTE
, op2(E
, R
), 0 },
686 /*03*/ { "add", TRUE
, LONG
, op2(E
, R
), 0 },
687 /*04*/ { "add", FALSE
, BYTE
, op2(Is
, A
), 0 },
688 /*05*/ { "add", FALSE
, LONG
, op2(Is
, A
), 0 },
689 /*06*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
690 /*07*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
692 /*08*/ { "or", TRUE
, BYTE
, op2(R
, E
), 0 },
693 /*09*/ { "or", TRUE
, LONG
, op2(R
, E
), 0 },
694 /*0a*/ { "or", TRUE
, BYTE
, op2(E
, R
), 0 },
695 /*0b*/ { "or", TRUE
, LONG
, op2(E
, R
), 0 },
696 /*0c*/ { "or", FALSE
, BYTE
, op2(I
, A
), 0 },
697 /*0d*/ { "or", FALSE
, LONG
, op2(I
, A
), 0 },
698 /*0e*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
699 /*0f*/ { "", FALSE
, NONE
, 0, 0 },
701 /*10*/ { "adc", TRUE
, BYTE
, op2(R
, E
), 0 },
702 /*11*/ { "adc", TRUE
, LONG
, op2(R
, E
), 0 },
703 /*12*/ { "adc", TRUE
, BYTE
, op2(E
, R
), 0 },
704 /*13*/ { "adc", TRUE
, LONG
, op2(E
, R
), 0 },
705 /*14*/ { "adc", FALSE
, BYTE
, op2(Is
, A
), 0 },
706 /*15*/ { "adc", FALSE
, LONG
, op2(Is
, A
), 0 },
707 /*16*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
708 /*17*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
710 /*18*/ { "sbb", TRUE
, BYTE
, op2(R
, E
), 0 },
711 /*19*/ { "sbb", TRUE
, LONG
, op2(R
, E
), 0 },
712 /*1a*/ { "sbb", TRUE
, BYTE
, op2(E
, R
), 0 },
713 /*1b*/ { "sbb", TRUE
, LONG
, op2(E
, R
), 0 },
714 /*1c*/ { "sbb", FALSE
, BYTE
, op2(Is
, A
), 0 },
715 /*1d*/ { "sbb", FALSE
, LONG
, op2(Is
, A
), 0 },
716 /*1e*/ { "push", FALSE
, NONE
, op1(Si
), 0 },
717 /*1f*/ { "pop", FALSE
, NONE
, op1(Si
), 0 },
719 /*20*/ { "and", TRUE
, BYTE
, op2(R
, E
), 0 },
720 /*21*/ { "and", TRUE
, LONG
, op2(R
, E
), 0 },
721 /*22*/ { "and", TRUE
, BYTE
, op2(E
, R
), 0 },
722 /*23*/ { "and", TRUE
, LONG
, op2(E
, R
), 0 },
723 /*24*/ { "and", FALSE
, BYTE
, op2(I
, A
), 0 },
724 /*25*/ { "and", FALSE
, LONG
, op2(I
, A
), 0 },
725 /*26*/ { "", FALSE
, NONE
, 0, 0 },
726 /*27*/ { "aaa", FALSE
, NONE
, 0, 0 },
728 /*28*/ { "sub", TRUE
, BYTE
, op2(R
, E
), 0 },
729 /*29*/ { "sub", TRUE
, LONG
, op2(R
, E
), 0 },
730 /*2a*/ { "sub", TRUE
, BYTE
, op2(E
, R
), 0 },
731 /*2b*/ { "sub", TRUE
, LONG
, op2(E
, R
), 0 },
732 /*2c*/ { "sub", FALSE
, BYTE
, op2(Is
, A
), 0 },
733 /*2d*/ { "sub", FALSE
, LONG
, op2(Is
, A
), 0 },
734 /*2e*/ { "", FALSE
, NONE
, 0, 0 },
735 /*2f*/ { "das", FALSE
, NONE
, 0, 0 },
737 /*30*/ { "xor", TRUE
, BYTE
, op2(R
, E
), 0 },
738 /*31*/ { "xor", TRUE
, LONG
, op2(R
, E
), 0 },
739 /*32*/ { "xor", TRUE
, BYTE
, op2(E
, R
), 0 },
740 /*33*/ { "xor", TRUE
, LONG
, op2(E
, R
), 0 },
741 /*34*/ { "xor", FALSE
, BYTE
, op2(I
, A
), 0 },
742 /*35*/ { "xor", FALSE
, LONG
, op2(I
, A
), 0 },
743 /*36*/ { "", FALSE
, NONE
, 0, 0 },
744 /*37*/ { "daa", FALSE
, NONE
, 0, 0 },
746 /*38*/ { "cmp", TRUE
, BYTE
, op2(R
, E
), 0 },
747 /*39*/ { "cmp", TRUE
, LONG
, op2(R
, E
), 0 },
748 /*3a*/ { "cmp", TRUE
, BYTE
, op2(E
, R
), 0 },
749 /*3b*/ { "cmp", TRUE
, LONG
, op2(E
, R
), 0 },
750 /*3c*/ { "cmp", FALSE
, BYTE
, op2(Is
, A
), 0 },
751 /*3d*/ { "cmp", FALSE
, LONG
, op2(Is
, A
), 0 },
752 /*3e*/ { "", FALSE
, NONE
, 0, 0 },
753 /*3f*/ { "aas", FALSE
, NONE
, 0, 0 },
755 /*40*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
756 /*41*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
757 /*42*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
758 /*43*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
759 /*44*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
760 /*45*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
761 /*46*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
762 /*47*/ { "inc", FALSE
, LONG
, op1(Ri
), 0 },
764 /*48*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
765 /*49*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
766 /*4a*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
767 /*4b*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
768 /*4c*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
769 /*4d*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
770 /*4e*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
771 /*4f*/ { "dec", FALSE
, LONG
, op1(Ri
), 0 },
773 /*50*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
774 /*51*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
775 /*52*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
776 /*53*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
777 /*54*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
778 /*55*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
779 /*56*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
780 /*57*/ { "push", FALSE
, LONG
, op1(Ri
), 0 },
782 /*58*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
783 /*59*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
784 /*5a*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
785 /*5b*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
786 /*5c*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
787 /*5d*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
788 /*5e*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
789 /*5f*/ { "pop", FALSE
, LONG
, op1(Ri
), 0 },
791 /*60*/ { "pusha", FALSE
, LONG
, 0, 0 },
792 /*61*/ { "popa", FALSE
, LONG
, 0, 0 },
793 /*62*/ { "bound", TRUE
, LONG
, op2(E
, R
), 0 },
794 /*63*/ { "arpl", TRUE
, NONE
, op2(Ew
,Rw
), 0 },
796 /*64*/ { "", FALSE
, NONE
, 0, 0 },
797 /*65*/ { "", FALSE
, NONE
, 0, 0 },
798 /*66*/ { "", FALSE
, NONE
, 0, 0 },
799 /*67*/ { "", FALSE
, NONE
, 0, 0 },
801 /*68*/ { "push", FALSE
, LONG
, op1(I
), 0 },
802 /*69*/ { "imul", TRUE
, LONG
, op3(I
,E
,R
), 0 },
803 /*6a*/ { "push", FALSE
, LONG
, op1(Ib
), 0 },
804 /*6b*/ { "imul", TRUE
, LONG
, op3(Ibs
,E
,R
),0 },
805 /*6c*/ { "ins", FALSE
, BYTE
, op2(DX
, DI
), 0 },
806 /*6d*/ { "ins", FALSE
, LONG
, op2(DX
, DI
), 0 },
807 /*6e*/ { "outs", FALSE
, BYTE
, op2(SI
, DX
), 0 },
808 /*6f*/ { "outs", FALSE
, LONG
, op2(SI
, DX
), 0 },
810 /*70*/ { "jo", FALSE
, NONE
, op1(Db
), 0 },
811 /*71*/ { "jno", FALSE
, NONE
, op1(Db
), 0 },
812 /*72*/ { "jb", FALSE
, NONE
, op1(Db
), 0 },
813 /*73*/ { "jnb", FALSE
, NONE
, op1(Db
), 0 },
814 /*74*/ { "jz", FALSE
, NONE
, op1(Db
), 0 },
815 /*75*/ { "jnz", FALSE
, NONE
, op1(Db
), 0 },
816 /*76*/ { "jbe", FALSE
, NONE
, op1(Db
), 0 },
817 /*77*/ { "jnbe", FALSE
, NONE
, op1(Db
), 0 },
819 /*78*/ { "js", FALSE
, NONE
, op1(Db
), 0 },
820 /*79*/ { "jns", FALSE
, NONE
, op1(Db
), 0 },
821 /*7a*/ { "jp", FALSE
, NONE
, op1(Db
), 0 },
822 /*7b*/ { "jnp", FALSE
, NONE
, op1(Db
), 0 },
823 /*7c*/ { "jl", FALSE
, NONE
, op1(Db
), 0 },
824 /*7d*/ { "jnl", FALSE
, NONE
, op1(Db
), 0 },
825 /*7e*/ { "jle", FALSE
, NONE
, op1(Db
), 0 },
826 /*7f*/ { "jnle", FALSE
, NONE
, op1(Db
), 0 },
828 /*80*/ { "", TRUE
, BYTE
, op2(I
, E
), (char *)db_Grp1
},
829 /*81*/ { "", TRUE
, LONG
, op2(I
, E
), (char *)db_Grp1
},
830 /*82*/ { "", TRUE
, BYTE
, op2(Is
,E
), (char *)db_Grp1
},
831 /*83*/ { "", TRUE
, LONG
, op2(Ibs
,E
), (char *)db_Grp1
},
832 /*84*/ { "test", TRUE
, BYTE
, op2(R
, E
), 0 },
833 /*85*/ { "test", TRUE
, LONG
, op2(R
, E
), 0 },
834 /*86*/ { "xchg", TRUE
, BYTE
, op2(R
, E
), 0 },
835 /*87*/ { "xchg", TRUE
, LONG
, op2(R
, E
), 0 },
837 /*88*/ { "mov", TRUE
, BYTE
, op2(R
, E
), 0 },
838 /*89*/ { "mov", TRUE
, LONG
, op2(R
, E
), 0 },
839 /*8a*/ { "mov", TRUE
, BYTE
, op2(E
, R
), 0 },
840 /*8b*/ { "mov", TRUE
, LONG
, op2(E
, R
), 0 },
841 /*8c*/ { "mov", TRUE
, NONE
, op2(S
, Ew
), 0 },
842 /*8d*/ { "lea", TRUE
, LONG
, op2(E
, R
), 0 },
843 /*8e*/ { "mov", TRUE
, NONE
, op2(Ew
, S
), 0 },
844 /*8f*/ { "pop", TRUE
, LONG
, op1(E
), 0 },
846 /*90*/ { "nop", FALSE
, NONE
, 0, 0 },
847 /*91*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
848 /*92*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
849 /*93*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
850 /*94*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
851 /*95*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
852 /*96*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
853 /*97*/ { "xchg", FALSE
, LONG
, op2(A
, Ri
), 0 },
855 /*98*/ { "cbw", FALSE
, SDEP
, 0, "cwde" }, /* cbw/cwde */
856 /*99*/ { "cwd", FALSE
, SDEP
, 0, "cdq" }, /* cwd/cdq */
857 /*9a*/ { "lcall", FALSE
, NONE
, op1(OS
), 0 },
858 /*9b*/ { "wait", FALSE
, NONE
, 0, 0 },
859 /*9c*/ { "pushf", FALSE
, LONG
, 0, 0 },
860 /*9d*/ { "popf", FALSE
, LONG
, 0, 0 },
861 /*9e*/ { "sahf", FALSE
, NONE
, 0, 0 },
862 /*9f*/ { "lahf", FALSE
, NONE
, 0, 0 },
864 /*a0*/ { "mov", FALSE
, BYTE
, op2(O
, A
), 0 },
865 /*a1*/ { "mov", FALSE
, LONG
, op2(O
, A
), 0 },
866 /*a2*/ { "mov", FALSE
, BYTE
, op2(A
, O
), 0 },
867 /*a3*/ { "mov", FALSE
, LONG
, op2(A
, O
), 0 },
868 /*a4*/ { "movs", FALSE
, BYTE
, op2(SI
,DI
), 0 },
869 /*a5*/ { "movs", FALSE
, LONG
, op2(SI
,DI
), 0 },
870 /*a6*/ { "cmps", FALSE
, BYTE
, op2(SI
,DI
), 0 },
871 /*a7*/ { "cmps", FALSE
, LONG
, op2(SI
,DI
), 0 },
873 /*a8*/ { "test", FALSE
, BYTE
, op2(I
, A
), 0 },
874 /*a9*/ { "test", FALSE
, LONG
, op2(I
, A
), 0 },
875 /*aa*/ { "stos", FALSE
, BYTE
, op1(DI
), 0 },
876 /*ab*/ { "stos", FALSE
, LONG
, op1(DI
), 0 },
877 /*ac*/ { "lods", FALSE
, BYTE
, op1(SI
), 0 },
878 /*ad*/ { "lods", FALSE
, LONG
, op1(SI
), 0 },
879 /*ae*/ { "scas", FALSE
, BYTE
, op1(SI
), 0 },
880 /*af*/ { "scas", FALSE
, LONG
, op1(SI
), 0 },
882 /*b0*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
883 /*b1*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
884 /*b2*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
885 /*b3*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
886 /*b4*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
887 /*b5*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
888 /*b6*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
889 /*b7*/ { "mov", FALSE
, BYTE
, op2(I
, Ri
), 0 },
891 /*b8*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
892 /*b9*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
893 /*ba*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
894 /*bb*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
895 /*bc*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
896 /*bd*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
897 /*be*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
898 /*bf*/ { "mov", FALSE
, LONG
, op2(I
, Ri
), 0 },
900 /*c0*/ { "", TRUE
, BYTE
, op2(Ib
, E
), (char *)db_Grp2
},
901 /*c1*/ { "", TRUE
, LONG
, op2(Ib
, E
), (char *)db_Grp2
},
902 /*c2*/ { "ret", FALSE
, NONE
, op1(Iw
), 0 },
903 /*c3*/ { "ret", FALSE
, NONE
, 0, 0 },
904 /*c4*/ { "les", TRUE
, LONG
, op2(E
, R
), 0 },
905 /*c5*/ { "lds", TRUE
, LONG
, op2(E
, R
), 0 },
906 /*c6*/ { "mov", TRUE
, BYTE
, op2(I
, E
), 0 },
907 /*c7*/ { "mov", TRUE
, LONG
, op2(I
, E
), 0 },
909 /*c8*/ { "enter", FALSE
, NONE
, op2(Ib
, Iw
), 0 },
910 /*c9*/ { "leave", FALSE
, NONE
, 0, 0 },
911 /*ca*/ { "lret", FALSE
, NONE
, op1(Iw
), 0 },
912 /*cb*/ { "lret", FALSE
, NONE
, 0, 0 },
913 /*cc*/ { "int", FALSE
, NONE
, op1(o3
), 0 },
914 /*cd*/ { "int", FALSE
, NONE
, op1(Ib
), 0 },
915 /*ce*/ { "into", FALSE
, NONE
, 0, 0 },
916 /*cf*/ { "iret", FALSE
, NONE
, 0, 0 },
918 /*d0*/ { "", TRUE
, BYTE
, op2(o1
, E
), (char *)db_Grp2
},
919 /*d1*/ { "", TRUE
, LONG
, op2(o1
, E
), (char *)db_Grp2
},
920 /*d2*/ { "", TRUE
, BYTE
, op2(CL
, E
), (char *)db_Grp2
},
921 /*d3*/ { "", TRUE
, LONG
, op2(CL
, E
), (char *)db_Grp2
},
922 /*d4*/ { "aam", TRUE
, NONE
, 0, 0 },
923 /*d5*/ { "aad", TRUE
, NONE
, 0, 0 },
924 /*d6*/ { "", FALSE
, NONE
, 0, 0 },
925 /*d7*/ { "xlat", FALSE
, BYTE
, op1(BX
), 0 },
927 /*d8*/ { "", TRUE
, NONE
, 0, (char *)db_Esc8
},
928 /*d9*/ { "", TRUE
, NONE
, 0, (char *)db_Esc9
},
929 /*da*/ { "", TRUE
, NONE
, 0, (char *)db_Esca
},
930 /*db*/ { "", TRUE
, NONE
, 0, (char *)db_Escb
},
931 /*dc*/ { "", TRUE
, NONE
, 0, (char *)db_Escc
},
932 /*dd*/ { "", TRUE
, NONE
, 0, (char *)db_Escd
},
933 /*de*/ { "", TRUE
, NONE
, 0, (char *)db_Esce
},
934 /*df*/ { "", TRUE
, NONE
, 0, (char *)db_Escf
},
936 /*e0*/ { "loopne",FALSE
, NONE
, op1(Db
), 0 },
937 /*e1*/ { "loope", FALSE
, NONE
, op1(Db
), 0 },
938 /*e2*/ { "loop", FALSE
, NONE
, op1(Db
), 0 },
939 /*e3*/ { "jcxz", FALSE
, SDEP
, op1(Db
), "jecxz" },
940 /*e4*/ { "in", FALSE
, BYTE
, op2(Ib
, A
), 0 },
941 /*e5*/ { "in", FALSE
, LONG
, op2(Ib
, A
) , 0 },
942 /*e6*/ { "out", FALSE
, BYTE
, op2(A
, Ib
), 0 },
943 /*e7*/ { "out", FALSE
, LONG
, op2(A
, Ib
) , 0 },
945 /*e8*/ { "call", FALSE
, NONE
, op1(Dl
), 0 },
946 /*e9*/ { "jmp", FALSE
, NONE
, op1(Dl
), 0 },
947 /*ea*/ { "ljmp", FALSE
, NONE
, op1(OS
), 0 },
948 /*eb*/ { "jmp", FALSE
, NONE
, op1(Db
), 0 },
949 /*ec*/ { "in", FALSE
, BYTE
, op2(DX
, A
), 0 },
950 /*ed*/ { "in", FALSE
, LONG
, op2(DX
, A
) , 0 },
951 /*ee*/ { "out", FALSE
, BYTE
, op2(A
, DX
), 0 },
952 /*ef*/ { "out", FALSE
, LONG
, op2(A
, DX
) , 0 },
954 /*f0*/ { "", FALSE
, NONE
, 0, 0 },
955 /*f1*/ { "", FALSE
, NONE
, 0, 0 },
956 /*f2*/ { "", FALSE
, NONE
, 0, 0 },
957 /*f3*/ { "", FALSE
, NONE
, 0, 0 },
958 /*f4*/ { "hlt", FALSE
, NONE
, 0, 0 },
959 /*f5*/ { "cmc", FALSE
, NONE
, 0, 0 },
960 /*f6*/ { "", TRUE
, BYTE
, 0, (char *)db_Grp3
},
961 /*f7*/ { "", TRUE
, LONG
, 0, (char *)db_Grp3
},
963 /*f8*/ { "clc", FALSE
, NONE
, 0, 0 },
964 /*f9*/ { "stc", FALSE
, NONE
, 0, 0 },
965 /*fa*/ { "cli", FALSE
, NONE
, 0, 0 },
966 /*fb*/ { "sti", FALSE
, NONE
, 0, 0 },
967 /*fc*/ { "cld", FALSE
, NONE
, 0, 0 },
968 /*fd*/ { "std", FALSE
, NONE
, 0, 0 },
969 /*fe*/ { "", TRUE
, NONE
, 0, (char *)db_Grp4
},
970 /*ff*/ { "", TRUE
, NONE
, 0, (char *)db_Grp5
},
973 struct inst db_bad_inst
=
974 { "???", FALSE
, NONE
, 0, 0 }
977 #define f_mod(byte) ((byte)>>6)
978 #define f_reg(byte) (((byte)>>3)&0x7)
979 #define f_rm(byte) ((byte)&0x7)
981 #define sib_ss(byte) ((byte)>>6)
982 #define sib_index(byte) (((byte)>>3)&0x7)
983 #define sib_base(byte) ((byte)&0x7)
985 char * db_index_reg_16
[8] = {
996 char * db_reg
[3][8] = {
997 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
998 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
999 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi"
1002 char * db_seg_reg
[8] = {
1003 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "", ""
1007 * lengths for size attributes
1009 int db_lengths
[] = {
1019 #define get_value_inc(result, loc, size, is_signed, task) \
1020 result = db_get_task_value((loc), (size), (is_signed), (task)); \
1024 * Read address at location and return updated location.
1031 struct i_addr
*addrp
, /* out */
1034 int mod
, rm
, sib
, index
, ss
, disp
;
1036 mod
= f_mod(regmodrm
);
1037 rm
= f_rm(regmodrm
);
1040 addrp
->is_reg
= TRUE
;
1044 addrp
->is_reg
= FALSE
;
1053 get_value_inc(disp
, loc
, 2, TRUE
, task
);
1059 addrp
->base
= db_index_reg_16
[rm
];
1063 get_value_inc(disp
, loc
, 1, TRUE
, task
);
1065 addrp
->base
= db_index_reg_16
[rm
];
1068 get_value_inc(disp
, loc
, 2, TRUE
, task
);
1070 addrp
->base
= db_index_reg_16
[rm
];
1075 if (mod
!= 3 && rm
== 4) {
1076 get_value_inc(sib
, loc
, 1, FALSE
, task
);
1078 index
= sib_index(sib
);
1080 addrp
->index
= db_reg
[LONG
][index
];
1081 addrp
->ss
= sib_ss(sib
);
1087 get_value_inc(addrp
->disp
, loc
, 4, FALSE
, task
);
1092 addrp
->base
= db_reg
[LONG
][rm
];
1097 get_value_inc(disp
, loc
, 1, TRUE
, task
);
1099 addrp
->base
= db_reg
[LONG
][rm
];
1103 get_value_inc(disp
, loc
, 4, FALSE
, task
);
1105 addrp
->base
= db_reg
[LONG
][rm
];
1116 struct i_addr
*addrp
,
1119 if (addrp
->is_reg
) {
1120 db_printf("%s", db_reg
[size
][addrp
->disp
]);
1125 db_printf("%s:", seg
);
1128 if (addrp
->base
!= 0 || addrp
->index
!= 0) {
1129 db_printf("%#n", addrp
->disp
);
1132 db_printf("%s", addrp
->base
);
1134 db_printf(",%s,%d", addrp
->index
, 1<<addrp
->ss
);
1137 db_task_printsym((db_addr_t
)addrp
->disp
, DB_STGY_ANY
, task
);
1141 * Disassemble floating-point ("escape") instruction
1142 * and return updated location.
1156 struct i_addr address
;
1159 get_value_inc(regmodrm
, loc
, 1, FALSE
, task
);
1160 fp
= &db_Esc_inst
[inst
- 0xd8][f_reg(regmodrm
)];
1161 mod
= f_mod(regmodrm
);
1164 * Normal address modes.
1166 loc
= db_read_address(loc
, short_addr
, regmodrm
, &address
, task
);
1167 db_printf(fp
->f_name
);
1168 switch(fp
->f_size
) {
1191 db_print_address(seg
, BYTE
, &address
, task
);
1195 * 'reg-reg' - special formats
1197 switch (fp
->f_rrmode
) {
1199 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1200 db_printf("%s\t%%st,%%st(%d)",name
,f_rm(regmodrm
));
1203 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1204 db_printf("%s\t%%st(%d),%%st",name
, f_rm(regmodrm
));
1207 name
= (fp
->f_rrname
) ? fp
->f_rrname
: fp
->f_name
;
1208 db_printf("%s\t%%st(%d)",name
, f_rm(regmodrm
));
1211 db_printf("%s", ((char **)fp
->f_rrname
)[f_rm(regmodrm
)]);
1214 db_printf("%s\t%%ax",
1215 ((char **)fp
->f_rrname
)[f_rm(regmodrm
)]);
1218 db_printf("<bad instruction>");
1227 * Disassemble instruction at 'loc'. 'altfmt' specifies an
1228 * (optional) alternate format. Return address of start of
1252 struct i_addr address
;
1256 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1273 case 0x66: /* data16 */
1280 short_addr
= !short_addr
;
1304 db_printf("repne ");
1307 db_printf("repe "); /* XXX repe VS rep */
1314 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1318 if (inst
>= 0xd8 && inst
<= 0xdf) {
1319 loc
= db_disasm_esc(loc
, inst
, short_addr
, size
, seg
, task
);
1325 get_value_inc(inst
, loc
, 1, FALSE
, task
);
1326 ip
= db_inst_0f
[inst
>>4];
1335 ip
= &db_inst_table
[inst
];
1337 if (ip
->i_has_modrm
) {
1338 get_value_inc(regmodrm
, loc
, 1, FALSE
, task
);
1339 loc
= db_read_address(loc
, short_addr
, regmodrm
, &address
, task
);
1342 i_name
= ip
->i_name
;
1343 i_size
= ip
->i_size
;
1344 i_mode
= ip
->i_mode
;
1346 if (ip
->i_extra
== (char *)db_Grp1
||
1347 ip
->i_extra
== (char *)db_Grp2
||
1348 ip
->i_extra
== (char *)db_Grp6
||
1349 ip
->i_extra
== (char *)db_Grp7
||
1350 ip
->i_extra
== (char *)db_Grp8
) {
1351 i_name
= ((char **)ip
->i_extra
)[f_reg(regmodrm
)];
1353 else if (ip
->i_extra
== (char *)db_Grp3
) {
1354 ip
= (struct inst
*)ip
->i_extra
;
1355 ip
= &ip
[f_reg(regmodrm
)];
1356 i_name
= ip
->i_name
;
1357 i_mode
= ip
->i_mode
;
1359 else if (ip
->i_extra
== (char *)db_Grp4
||
1360 ip
->i_extra
== (char *)db_Grp5
) {
1361 ip
= (struct inst
*)ip
->i_extra
;
1362 ip
= &ip
[f_reg(regmodrm
)];
1363 i_name
= ip
->i_name
;
1364 i_mode
= ip
->i_mode
;
1365 i_size
= ip
->i_size
;
1368 if (i_size
== SDEP
) {
1372 db_printf(ip
->i_extra
);
1376 if (i_size
!= NONE
) {
1377 if (i_size
== BYTE
) {
1381 else if (i_size
== WORD
) {
1385 else if (size
== WORD
)
1394 i_mode
>>= 8, first
= FALSE
)
1399 switch (i_mode
& 0xFF) {
1402 db_print_address(seg
, size
, &address
, task
);
1407 db_print_address(seg
, size
, &address
, task
);
1411 db_print_address(seg
, WORD
, &address
, task
);
1415 db_print_address(seg
, BYTE
, &address
, task
);
1419 db_printf("%s", db_reg
[size
][f_reg(regmodrm
)]);
1423 db_printf("%s", db_reg
[WORD
][f_reg(regmodrm
)]);
1427 db_printf("%s", db_reg
[size
][f_rm(inst
)]);
1431 db_printf("%s", db_seg_reg
[f_reg(regmodrm
)]);
1435 db_printf("%s", db_seg_reg
[f_reg(inst
)]);
1439 db_printf("%s", db_reg
[size
][0]); /* acc */
1444 db_printf("%s:", seg
);
1445 db_printf("(%s)", short_addr
? "%bx" : "%ebx");
1458 db_printf("%s:", seg
);
1459 db_printf("(%s)", short_addr
? "%si" : "%esi");
1463 db_printf("%%es:(%s)", short_addr
? "%di" : "%edi");
1467 db_printf("%%cr%d", f_reg(regmodrm
));
1471 db_printf("%%dr%d", f_reg(regmodrm
));
1475 db_printf("%%tr%d", f_reg(regmodrm
));
1479 len
= db_lengths
[size
];
1480 get_value_inc(imm
, loc
, len
, FALSE
, task
);/* unsigned */
1481 db_printf("$%#n", imm
);
1485 len
= db_lengths
[size
];
1486 get_value_inc(imm
, loc
, len
, TRUE
, task
); /* signed */
1487 db_printf("$%#r", imm
);
1491 get_value_inc(imm
, loc
, 1, FALSE
, task
); /* unsigned */
1492 db_printf("$%#n", imm
);
1496 get_value_inc(imm
, loc
, 1, TRUE
, task
); /* signed */
1497 db_printf("$%#r", imm
);
1501 get_value_inc(imm
, loc
, 2, FALSE
, task
); /* unsigned */
1502 db_printf("$%#n", imm
);
1506 get_value_inc(imm
, loc
, 4, FALSE
, task
);
1507 db_printf("$%#n", imm
);
1512 get_value_inc(displ
, loc
, 2, TRUE
, task
);
1515 get_value_inc(displ
, loc
, 4, TRUE
, task
);
1518 db_printf("%s:%#r",seg
, displ
);
1520 db_task_printsym((db_addr_t
)displ
, DB_STGY_ANY
, task
);
1524 get_value_inc(displ
, loc
, 1, TRUE
, task
);
1526 /* offset only affects low 16 bits */
1527 displ
= (loc
& 0xffff0000)
1528 | ((loc
+ displ
) & 0xffff);
1531 displ
= displ
+ loc
;
1532 db_task_printsym((db_addr_t
)displ
,DB_STGY_ANY
,task
);
1533 if (db_line_at_pc(0, &filename
, &linenum
, displ
)) {
1534 db_printf(" [%s", filename
);
1536 db_printf(":%d", linenum
);
1543 get_value_inc(displ
, loc
, 2, TRUE
, task
);
1544 /* offset only affects low 16 bits */
1545 displ
= (loc
& 0xffff0000)
1546 | ((loc
+ displ
) & 0xffff);
1549 get_value_inc(displ
, loc
, 4, TRUE
, task
);
1550 displ
= displ
+ loc
;
1552 db_task_printsym((db_addr_t
)displ
, DB_STGY_ANY
, task
);
1553 if (db_line_at_pc(0, &filename
, &linenum
, displ
)) {
1554 db_printf(" [%s", filename
);
1556 db_printf(":%d", linenum
);
1571 get_value_inc(imm
, loc
, 2, FALSE
, task
); /* offset */
1574 get_value_inc(imm
, loc
, 4, FALSE
, task
); /* offset */
1576 get_value_inc(imm2
, loc
, 2, FALSE
, task
); /* segment */
1577 db_printf("$%#n,%#n", imm2
, imm
);
1582 if (altfmt
== 0 && !db_disasm_16
) {
1583 if (inst
== 0xe9 || inst
== 0xeb) { /* jmp, Dl or Db */
1585 * GAS pads to longword boundary after unconditional jumps.
1587 while (loc
& (4-1)) {
1588 get_value_inc(inst
, loc
, 0, FALSE
, task
);
1589 if (inst
!= 0x90) /* nop */
1600 * Classify instructions by whether they read or write memory.
1603 #define DBLS_LOAD 0x01 /* instruction reads from memory */
1604 #define DBLS_STORE 0x02 /* instruction writes to memory */
1606 #define DBLS_MODRM 0x10 /* instruction uses mod r/m byte */
1607 #define DBLS_SECOND 0x20 /* instruction does two operations */
1608 #define DBLS_ESCAPE 0x40 /* escape to two-byte opcodes */
1609 #define DBLS_SWREG 0x80 /* need to switch on reg bits of mod r/m */
1611 #define DBLS_MODS 0xf0
1612 #define DBLS_LMASK (DBLS_MODS|DBLS_LOAD)
1613 #define DBLS_SMASK (DBLS_MODS|DBLS_STORE)
1615 char db_ldstrtab
[] = {
1616 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1617 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x40,
1618 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
1619 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x02, 0x01,
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,
1623 0x12, 0x12, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00,
1625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1627 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1628 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1629 0x02, 0x01, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
1630 0x02, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
1631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1634 0x12, 0x12, 0x00, 0x12, 0x11, 0x11, 0x13, 0x13,
1635 0x12, 0x12, 0x11, 0x11, 0x12, 0x00, 0x11, 0x03,
1636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1637 0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x00, 0x00,
1638 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x21, 0x21,
1639 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
1640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643 0x13, 0x13, 0x00, 0x00, 0x01, 0x01, 0x12, 0x12,
1644 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x01,
1646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
1650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x13,
1653 unsigned char db_ldstrtab0f
[] = {
1654 0x80, 0x80, 0x11, 0x11, 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,
1661 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,
1670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
1675 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
1676 0x02, 0x01, 0x00, 0x11, 0x13, 0x13, 0x00, 0x00,
1677 0x02, 0x01, 0x12, 0x13, 0x13, 0x13, 0x00, 0x11,
1678 0x00, 0x00, 0x01, 0x13, 0x01, 0x01, 0x11, 0x11,
1679 0x00, 0x00, 0x80, 0x13, 0x13, 0x13, 0x11, 0x11,
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,
1688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1691 int db_inst_swreg(boolean_t
, unsigned long, unsigned char);
1694 * Given four bytes of instruction (stored as an int, not an
1695 * array of characters), compute if the instruction reads
1702 unsigned char insb
, bits
;
1706 bits
= db_ldstrtab
[insb
];
1707 if (!(bits
& DBLS_LOAD
))
1710 switch (bits
& DBLS_MODS
) {
1715 return ((insb
& 0xc0) != 0xc0);
1716 case DBLS_SECOND
|DBLS_MODRM
:
1718 return ((insb
& 0xc0) != 0xc0 ? 2 : 0);
1724 bits
= db_ldstrtab0f
[insb
];
1727 return (db_inst_swreg(TRUE
, insw
, insb
));
1729 panic ("db_inst_load: unknown mod bits");
1735 * Given four bytes of instruction (stored as an int, not an
1736 * array of characters), compute if the instruction writes
1743 unsigned char insb
, bits
;
1747 bits
= db_ldstrtab
[insb
];
1748 if (!(bits
& DBLS_STORE
))
1751 switch (bits
& DBLS_MODS
) {
1756 return ((insb
& 0xc0) != 0xc0);
1757 case DBLS_SECOND
|DBLS_MODRM
:
1759 return ((insb
& 0xc0) != 0xc0 ? 2 : 0);
1765 bits
= db_ldstrtab0f
[insb
];
1768 return (db_inst_swreg(FALSE
, insw
, insb
));
1770 panic ("db_inst_store: unknown mod bits");
1776 * Parse a mod r/m byte to see if extended opcode reads
1785 unsigned char modrm
= insw
& 0xff;
1789 switch (modrm
& 0x38) {
1794 return ((modrm
& 0xc0) != 0xc0);
1798 switch (modrm
& 0x38) {
1803 return ((modrm
& 0xc0) != 0xc0 ? 2 : 0);
1806 return ((modrm
& 0xc0) != 0xc0);
1811 return ((modrm
& 0xc0) != 0xc0);
1812 switch (modrm
& 0x38) {
1816 return ((modrm
& 0xc0) != 0xc0);