1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 1989, 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 * modified by John Hassey (hassey@dg-rtp.dg.com)
27 * The main tables describing the instructions is essentially a copy
28 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 * Programmers Manual. Usually, there is a capital letter, followed
30 * by a small letter. The capital letter tell the addressing mode,
31 * and the small letter tells about the operand size. Refer to
32 * the Intel manual for details.
44 /* Points to first byte not fetched. */
45 bfd_byte
*max_fetched
;
46 bfd_byte the_buffer
[MAXLEN
];
51 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
52 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
54 #define FETCH_DATA(info, addr) \
55 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
56 ? 1 : fetch_data ((info), (addr)))
59 fetch_data (info
, addr
)
60 struct disassemble_info
*info
;
64 struct dis_private
*priv
= (struct dis_private
*)info
->private_data
;
65 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
67 status
= (*info
->read_memory_func
) (start
,
69 addr
- priv
->max_fetched
,
73 (*info
->memory_error_func
) (status
, start
, info
);
74 longjmp (priv
->bailout
, 1);
77 priv
->max_fetched
= addr
;
81 #define Eb OP_E, b_mode
82 #define indirEb OP_indirE, b_mode
83 #define Gb OP_G, b_mode
84 #define Ev OP_E, v_mode
85 #define indirEv OP_indirE, v_mode
86 #define Ew OP_E, w_mode
87 #define Ma OP_E, v_mode
89 #define Mp OP_E, 0 /* ? */
90 #define Gv OP_G, v_mode
91 #define Gw OP_G, w_mode
92 #define Rw OP_rm, w_mode
93 #define Rd OP_rm, d_mode
94 #define Ib OP_I, b_mode
95 #define sIb OP_sI, b_mode /* sign extened byte */
96 #define Iv OP_I, v_mode
97 #define Iw OP_I, w_mode
98 #define Jb OP_J, b_mode
99 #define Jv OP_J, v_mode
100 #define ONE OP_ONE, 0
101 #define Cd OP_C, d_mode
102 #define Dd OP_D, d_mode
103 #define Td OP_T, d_mode
105 #define eAX OP_REG, eAX_reg
106 #define eBX OP_REG, eBX_reg
107 #define eCX OP_REG, eCX_reg
108 #define eDX OP_REG, eDX_reg
109 #define eSP OP_REG, eSP_reg
110 #define eBP OP_REG, eBP_reg
111 #define eSI OP_REG, eSI_reg
112 #define eDI OP_REG, eDI_reg
113 #define AL OP_REG, al_reg
114 #define CL OP_REG, cl_reg
115 #define DL OP_REG, dl_reg
116 #define BL OP_REG, bl_reg
117 #define AH OP_REG, ah_reg
118 #define CH OP_REG, ch_reg
119 #define DH OP_REG, dh_reg
120 #define BH OP_REG, bh_reg
121 #define AX OP_REG, ax_reg
122 #define DX OP_REG, dx_reg
123 #define indirDX OP_REG, indir_dx_reg
125 #define Sw OP_SEG, w_mode
126 #define Ap OP_DIR, lptr
127 #define Av OP_DIR, v_mode
128 #define Ob OP_OFF, b_mode
129 #define Ov OP_OFF, v_mode
130 #define Xb OP_DSSI, b_mode
131 #define Xv OP_DSSI, v_mode
132 #define Yb OP_ESDI, b_mode
133 #define Yv OP_ESDI, v_mode
135 #define es OP_REG, es_reg
136 #define ss OP_REG, ss_reg
137 #define cs OP_REG, cs_reg
138 #define ds OP_REG, ds_reg
139 #define fs OP_REG, fs_reg
140 #define gs OP_REG, gs_reg
142 int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
143 int OP_J(), OP_SEG();
144 int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
145 int OP_D(), OP_T(), OP_rm();
147 static void dofloat (), putop (), append_prefix (), set_op ();
148 static int get16 (), get32 ();
190 #define indir_dx_reg 150
192 #define GRP1b NULL, NULL, 0
193 #define GRP1S NULL, NULL, 1
194 #define GRP1Ss NULL, NULL, 2
195 #define GRP2b NULL, NULL, 3
196 #define GRP2S NULL, NULL, 4
197 #define GRP2b_one NULL, NULL, 5
198 #define GRP2S_one NULL, NULL, 6
199 #define GRP2b_cl NULL, NULL, 7
200 #define GRP2S_cl NULL, NULL, 8
201 #define GRP3b NULL, NULL, 9
202 #define GRP3S NULL, NULL, 10
203 #define GRP4 NULL, NULL, 11
204 #define GRP5 NULL, NULL, 12
205 #define GRP6 NULL, NULL, 13
206 #define GRP7 NULL, NULL, 14
207 #define GRP8 NULL, NULL, 15
208 #define GRP9 NULL, NULL, 16
211 #define FLOAT NULL, NULL, FLOATCODE
223 struct dis386 dis386
[] = {
241 { "(bad)" }, /* 0x0f extended opcode escape */
267 { "(bad)" }, /* SEG ES prefix */
276 { "(bad)" }, /* SEG CS prefix */
285 { "(bad)" }, /* SEG SS prefix */
294 { "(bad)" }, /* SEG DS prefix */
335 { "boundS", Gv
, Ma
},
337 { "(bad)" }, /* seg fs */
338 { "(bad)" }, /* seg gs */
339 { "(bad)" }, /* op size prefix */
340 { "(bad)" }, /* adr size prefix */
342 { "pushS", Iv
}, /* 386 book wrong */
343 { "imulS", Gv
, Ev
, Iv
},
344 { "pushl", sIb
}, /* push of byte really pushes 4 bytes */
345 { "imulS", Gv
, Ev
, Ib
},
346 { "insb", Yb
, indirDX
},
347 { "insS", Yv
, indirDX
},
348 { "outsb", indirDX
, Xb
},
349 { "outsS", indirDX
, Xv
},
388 { "xchgS", eCX
, eAX
},
389 { "xchgS", eDX
, eAX
},
390 { "xchgS", eBX
, eAX
},
391 { "xchgS", eSP
, eAX
},
392 { "xchgS", eBP
, eAX
},
393 { "xchgS", eSI
, eAX
},
394 { "xchgS", eDI
, eAX
},
399 { "(bad)" }, /* fwait */
415 { "testS", eAX
, Iv
},
417 { "stosS", Yv
, eAX
},
419 { "lodsS", eAX
, Xv
},
421 { "scasS", eAX
, Yv
},
490 { "inb", AL
, indirDX
},
491 { "inS", eAX
, indirDX
},
492 { "outb", indirDX
, AL
},
493 { "outS", indirDX
, eAX
},
495 { "(bad)" }, /* lock prefix */
497 { "(bad)" }, /* repne */
498 { "(bad)" }, /* repz */
514 struct dis386 dis386_twobyte
[] = {
527 { "(bad)" }, { "ud2a" },
528 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
530 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
531 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
533 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
534 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
536 /* these are all backward in appendix A of the intel book */
546 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
547 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
549 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
550 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
552 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
553 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
555 { "cmovo", Gv
,Ev
}, { "cmovno", Gv
,Ev
}, { "cmovb", Gv
,Ev
}, { "cmovae", Gv
,Ev
},
556 { "cmove", Gv
,Ev
}, { "cmovne", Gv
,Ev
}, { "cmovbe", Gv
,Ev
}, { "cmova", Gv
,Ev
},
558 { "cmovs", Gv
,Ev
}, { "cmovns", Gv
,Ev
}, { "cmovp", Gv
,Ev
}, { "cmovnp", Gv
,Ev
},
559 { "cmovl", Gv
,Ev
}, { "cmovge", Gv
,Ev
}, { "cmovle", Gv
,Ev
}, { "cmovg", Gv
,Ev
},
561 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
562 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
564 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
565 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
567 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
568 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
570 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
571 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
573 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
574 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
576 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
577 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
619 { "shldS", Ev
, Gv
, Ib
},
620 { "shldS", Ev
, Gv
, CL
},
628 { "shrdS", Ev
, Gv
, Ib
},
629 { "shrdS", Ev
, Gv
, CL
},
633 { "cmpxchgb", Eb
, Gb
},
634 { "cmpxchgS", Ev
, Gv
},
635 { "lssS", Gv
, Mp
}, /* 386 lists only Mp */
637 { "lfsS", Gv
, Mp
}, /* 386 lists only Mp */
638 { "lgsS", Gv
, Mp
}, /* 386 lists only Mp */
639 { "movzbS", Gv
, Eb
},
640 { "movzwS", Gv
, Ew
},
648 { "movsbS", Gv
, Eb
},
649 { "movswS", Gv
, Ew
},
669 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
670 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
672 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
673 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
675 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
676 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
678 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
679 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
681 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
682 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
684 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
685 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
688 static char obuf
[100];
690 static char scratchbuf
[100];
691 static unsigned char *start_codep
;
692 static unsigned char *codep
;
693 static disassemble_info
*the_info
;
697 static void oappend ();
699 static char *names32
[]={
700 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
702 static char *names16
[] = {
703 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
705 static char *names8
[] = {
706 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
708 static char *names_seg
[] = {
709 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
712 struct dis386 grps
[][8] = {
830 { "imulS", eAX
, Ev
},
832 { "idivS", eAX
, Ev
},
850 { "lcall", indirEv
},
902 #define PREFIX_REPZ 1
903 #define PREFIX_REPNZ 2
904 #define PREFIX_LOCK 4
906 #define PREFIX_SS 0x10
907 #define PREFIX_DS 0x20
908 #define PREFIX_ES 0x40
909 #define PREFIX_FS 0x80
910 #define PREFIX_GS 0x100
911 #define PREFIX_DATA 0x200
912 #define PREFIX_ADR 0x400
913 #define PREFIX_FWAIT 0x800
923 FETCH_DATA (the_info
, codep
+ 1);
927 prefixes
|= PREFIX_REPZ
;
930 prefixes
|= PREFIX_REPNZ
;
933 prefixes
|= PREFIX_LOCK
;
936 prefixes
|= PREFIX_CS
;
939 prefixes
|= PREFIX_SS
;
942 prefixes
|= PREFIX_DS
;
945 prefixes
|= PREFIX_ES
;
948 prefixes
|= PREFIX_FS
;
951 prefixes
|= PREFIX_GS
;
954 prefixes
|= PREFIX_DATA
;
957 prefixes
|= PREFIX_ADR
;
960 prefixes
|= PREFIX_FWAIT
;
972 static char op1out
[100], op2out
[100], op3out
[100];
973 static int op_address
[3], op_ad
, op_index
[3];
978 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
979 * (see topic "Redundant prefixes" in the "Differences from 8086"
980 * section of the "Virtual 8086 Mode" chapter.)
981 * 'pc' should be the address of this instruction, it will
982 * be used to print the target address if this is a relative jump or call
983 * The function returns the length of this instruction in bytes.
987 print_insn_i386 (pc
, info
)
989 disassemble_info
*info
;
993 int enter_instruction
;
994 char *first
, *second
, *third
;
997 struct dis_private priv
;
998 bfd_byte
*inbuf
= priv
.the_buffer
;
1000 info
->private_data
= (PTR
) &priv
;
1001 priv
.max_fetched
= priv
.the_buffer
;
1002 priv
.insn_start
= pc
;
1003 if (setjmp (priv
.bailout
) != 0)
1012 op_index
[0] = op_index
[1] = op_index
[2] = -1;
1016 start_codep
= inbuf
;
1021 FETCH_DATA (info
, codep
+ 1);
1023 enter_instruction
= 1;
1025 enter_instruction
= 0;
1029 if (prefixes
& PREFIX_REPZ
)
1031 if (prefixes
& PREFIX_REPNZ
)
1033 if (prefixes
& PREFIX_LOCK
)
1036 if ((prefixes
& PREFIX_FWAIT
)
1037 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
1039 /* fwait not followed by floating point instruction */
1040 (*info
->fprintf_func
) (info
->stream
, "fwait");
1044 /* these would be initialized to 0 if disassembling for 8086 or 286 */
1048 if (prefixes
& PREFIX_DATA
)
1051 if (prefixes
& PREFIX_ADR
)
1054 oappend ("addr16 ");
1059 FETCH_DATA (info
, codep
+ 2);
1060 dp
= &dis386_twobyte
[*++codep
];
1063 dp
= &dis386
[*codep
];
1066 /* Fetch the mod/reg/rm byte. FIXME: We should be only fetching
1067 this if we need it. As it is, this code loses if there is a
1068 one-byte instruction (without a mod/reg/rm byte) at the end of
1069 the address space. */
1071 FETCH_DATA (info
, codep
+ 1);
1072 mod
= (*codep
>> 6) & 3;
1073 reg
= (*codep
>> 3) & 7;
1076 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
1082 if (dp
->name
== NULL
)
1083 dp
= &grps
[dp
->bytemode1
][reg
];
1090 (*dp
->op1
)(dp
->bytemode1
);
1095 (*dp
->op2
)(dp
->bytemode2
);
1100 (*dp
->op3
)(dp
->bytemode3
);
1103 obufp
= obuf
+ strlen (obuf
);
1104 for (i
= strlen (obuf
); i
< 6; i
++)
1107 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
1109 /* enter instruction is printed with operands in the
1110 * same order as the intel book; everything else
1111 * is printed in reverse order
1113 if (enter_instruction
)
1118 op_ad
= op_index
[0];
1119 op_index
[0] = op_index
[2];
1120 op_index
[2] = op_ad
;
1131 if (op_index
[0] != -1)
1132 (*info
->print_address_func
) (op_address
[op_index
[0]], info
);
1134 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
1140 (*info
->fprintf_func
) (info
->stream
, ",");
1141 if (op_index
[1] != -1)
1142 (*info
->print_address_func
) (op_address
[op_index
[1]], info
);
1144 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
1150 (*info
->fprintf_func
) (info
->stream
, ",");
1151 if (op_index
[2] != -1)
1152 (*info
->print_address_func
) (op_address
[op_index
[2]], info
);
1154 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
1156 return (codep
- inbuf
);
1159 char *float_mem
[] = {
1235 #define STi OP_STi, 0
1236 int OP_ST(), OP_STi();
1238 #define FGRPd9_2 NULL, NULL, 0
1239 #define FGRPd9_4 NULL, NULL, 1
1240 #define FGRPd9_5 NULL, NULL, 2
1241 #define FGRPd9_6 NULL, NULL, 3
1242 #define FGRPd9_7 NULL, NULL, 4
1243 #define FGRPda_5 NULL, NULL, 5
1244 #define FGRPdb_4 NULL, NULL, 6
1245 #define FGRPde_3 NULL, NULL, 7
1246 #define FGRPdf_4 NULL, NULL, 8
1248 struct dis386 float_reg
[][8] = {
1251 { "fadd", ST
, STi
},
1252 { "fmul", ST
, STi
},
1255 { "fsub", ST
, STi
},
1256 { "fsubr", ST
, STi
},
1257 { "fdiv", ST
, STi
},
1258 { "fdivr", ST
, STi
},
1273 { "fcmovb", ST
, STi
},
1274 { "fcmove", ST
, STi
},
1275 { "fcmovbe",ST
, STi
},
1276 { "fcmovu", ST
, STi
},
1284 { "fcmovnb",ST
, STi
},
1285 { "fcmovne",ST
, STi
},
1286 { "fcmovnbe",ST
, STi
},
1287 { "fcmovnu",ST
, STi
},
1289 { "fucomi", ST
, STi
},
1290 { "fcomi", ST
, STi
},
1295 { "fadd", STi
, ST
},
1296 { "fmul", STi
, ST
},
1299 { "fsub", STi
, ST
},
1300 { "fsubr", STi
, ST
},
1301 { "fdiv", STi
, ST
},
1302 { "fdivr", STi
, ST
},
1317 { "faddp", STi
, ST
},
1318 { "fmulp", STi
, ST
},
1321 { "fsubp", STi
, ST
},
1322 { "fsubrp", STi
, ST
},
1323 { "fdivp", STi
, ST
},
1324 { "fdivrp", STi
, ST
},
1333 { "fucomip",ST
, STi
},
1334 { "fcomip", ST
, STi
},
1340 char *fgrps
[][8] = {
1343 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1348 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1353 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1358 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1363 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1368 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1373 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1374 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1379 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1384 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1392 unsigned char floatop
;
1394 floatop
= codep
[-1];
1398 putop (float_mem
[(floatop
- 0xd8) * 8 + reg
]);
1405 dp
= &float_reg
[floatop
- 0xd8][reg
];
1406 if (dp
->name
== NULL
)
1408 putop (fgrps
[dp
->bytemode1
][rm
]);
1409 /* instruction fnstsw is only one with strange arg */
1411 && FETCH_DATA (the_info
, codep
+ 1)
1413 strcpy (op1out
, "%eax");
1420 (*dp
->op1
)(dp
->bytemode1
);
1423 (*dp
->op2
)(dp
->bytemode2
);
1441 sprintf (scratchbuf
, "%%st(%d)", rm
);
1442 oappend (scratchbuf
);
1447 /* capital letters in template are macros */
1454 for (p
= template; *p
; p
++)
1461 case 'C': /* For jcxz/jecxz */
1466 if ((prefixes
& PREFIX_FWAIT
) == 0)
1470 /* operand size flag */
1486 obufp
+= strlen (s
);
1493 if (prefixes
& PREFIX_CS
)
1495 if (prefixes
& PREFIX_DS
)
1497 if (prefixes
& PREFIX_SS
)
1499 if (prefixes
& PREFIX_ES
)
1501 if (prefixes
& PREFIX_FS
)
1503 if (prefixes
& PREFIX_GS
)
1508 OP_indirE (bytemode
)
1527 /* skip mod/rm byte */
1539 oappend (names8
[rm
]);
1542 oappend (names16
[rm
]);
1546 oappend (names32
[rm
]);
1548 oappend (names16
[rm
]);
1551 oappend ("<bad dis table>");
1562 FETCH_DATA (the_info
, codep
+ 1);
1563 scale
= (*codep
>> 6) & 3;
1564 index
= (*codep
>> 3) & 7;
1575 /* implies havesib and havebase */
1591 FETCH_DATA (the_info
, codep
+ 1);
1592 disp
= *(char *)codep
++;
1609 if (mod
!= 0 || rm
== 5 || (havesib
&& base
== 5))
1611 sprintf (scratchbuf
, "0x%x", disp
);
1612 oappend (scratchbuf
);
1615 if (havebase
|| havesib
)
1619 oappend (names32
[base
]);
1624 sprintf (scratchbuf
, ",%s", names32
[index
]);
1625 oappend (scratchbuf
);
1627 sprintf (scratchbuf
, ",%d", 1 << scale
);
1628 oappend (scratchbuf
);
1642 oappend (names8
[reg
]);
1645 oappend (names16
[reg
]);
1648 oappend (names32
[reg
]);
1652 oappend (names32
[reg
]);
1654 oappend (names16
[reg
]);
1657 oappend ("<internal disassembler error>");
1668 FETCH_DATA (the_info
, codep
+ 4);
1669 x
= *codep
++ & 0xff;
1670 x
|= (*codep
++ & 0xff) << 8;
1671 x
|= (*codep
++ & 0xff) << 16;
1672 x
|= (*codep
++ & 0xff) << 24;
1681 FETCH_DATA (the_info
, codep
+ 2);
1682 x
= *codep
++ & 0xff;
1683 x
|= (*codep
++ & 0xff) << 8;
1691 op_index
[op_ad
] = op_ad
;
1692 op_address
[op_ad
] = op
;
1703 case indir_dx_reg
: s
= "(%dx)"; break;
1704 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
1705 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
1706 s
= names16
[code
- ax_reg
];
1708 case es_reg
: case ss_reg
: case cs_reg
:
1709 case ds_reg
: case fs_reg
: case gs_reg
:
1710 s
= names_seg
[code
- es_reg
];
1712 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
1713 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
1714 s
= names8
[code
- al_reg
];
1716 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
1717 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
1719 s
= names32
[code
- eAX_reg
];
1721 s
= names16
[code
- eAX_reg
];
1724 s
= "<internal disassembler error>";
1740 FETCH_DATA (the_info
, codep
+ 1);
1741 op
= *codep
++ & 0xff;
1753 oappend ("<internal disassembler error>");
1756 sprintf (scratchbuf
, "$0x%x", op
);
1757 oappend (scratchbuf
);
1770 FETCH_DATA (the_info
, codep
+ 1);
1771 op
= *(char *)codep
++;
1777 op
= (short)get16();
1780 op
= (short)get16 ();
1783 oappend ("<internal disassembler error>");
1786 sprintf (scratchbuf
, "$0x%x", op
);
1787 oappend (scratchbuf
);
1801 FETCH_DATA (the_info
, codep
+ 1);
1802 disp
= *(char *)codep
++;
1809 disp
= (short)get16 ();
1810 /* for some reason, a data16 prefix on a jump instruction
1811 means that the pc is masked to 16 bits after the
1812 displacement is added! */
1817 oappend ("<internal disassembler error>");
1820 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
1822 sprintf (scratchbuf
, "0x%x", disp
);
1823 oappend (scratchbuf
);
1832 static char *sreg
[] = {
1833 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1836 oappend (sreg
[reg
]);
1859 sprintf (scratchbuf
, "0x%x,0x%x", seg
, offset
);
1860 oappend (scratchbuf
);
1866 offset
= (short)get16 ();
1868 offset
= start_pc
+ codep
- start_codep
+ offset
;
1870 sprintf (scratchbuf
, "0x%x", offset
);
1871 oappend (scratchbuf
);
1874 oappend ("<internal disassembler error>");
1892 sprintf (scratchbuf
, "0x%x", off
);
1893 oappend (scratchbuf
);
1903 oappend (aflag
? "%edi" : "%di");
1914 oappend (aflag
? "%esi" : "%si");
1933 codep
++; /* skip mod/rm */
1934 sprintf (scratchbuf
, "%%cr%d", reg
);
1935 oappend (scratchbuf
);
1944 codep
++; /* skip mod/rm */
1945 sprintf (scratchbuf
, "%%db%d", reg
);
1946 oappend (scratchbuf
);
1955 codep
++; /* skip mod/rm */
1956 sprintf (scratchbuf
, "%%tr%d", reg
);
1957 oappend (scratchbuf
);
1968 oappend (names32
[rm
]);
1971 oappend (names16
[rm
]);
This page took 0.102744 seconds and 5 git commands to generate.