1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 89, 91, 93, 94, 95, 1996 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 const unsigned char onebyte_has_modrm[256] = {
689 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
690 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
691 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
692 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
693 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
694 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
695 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
697 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
698 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
701 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
702 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
704 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
707 static const unsigned char twobyte_has_modrm[256] = {
708 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
709 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
710 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
712 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
713 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
714 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
715 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
717 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
718 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,
719 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,
720 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
721 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
722 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
723 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
726 static char obuf[100];
728 static char scratchbuf[100];
729 static unsigned char *start_codep;
730 static unsigned char *codep;
731 static disassemble_info *the_info;
735 static void oappend ();
737 static char *names32[]={
738 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
740 static char *names16[] = {
741 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
743 static char *names8[] = {
744 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
746 static char *names_seg[] = {
747 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
749 static char *index16[] = {
750 "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
753 struct dis386 grps[][8] = {
871 { "imulS", eAX, Ev },
873 { "idivS", eAX, Ev },
891 { "lcall", indirEv },
943 #define PREFIX_REPZ 1
944 #define PREFIX_REPNZ 2
945 #define PREFIX_LOCK 4
947 #define PREFIX_SS 0x10
948 #define PREFIX_DS 0x20
949 #define PREFIX_ES 0x40
950 #define PREFIX_FS 0x80
951 #define PREFIX_GS 0x100
952 #define PREFIX_DATA 0x200
953 #define PREFIX_ADR 0x400
954 #define PREFIX_FWAIT 0x800
964 FETCH_DATA (the_info, codep + 1);
968 prefixes |= PREFIX_REPZ;
971 prefixes |= PREFIX_REPNZ;
974 prefixes |= PREFIX_LOCK;
977 prefixes |= PREFIX_CS;
980 prefixes |= PREFIX_SS;
983 prefixes |= PREFIX_DS;
986 prefixes |= PREFIX_ES;
989 prefixes |= PREFIX_FS;
992 prefixes |= PREFIX_GS;
995 prefixes |= PREFIX_DATA;
998 prefixes |= PREFIX_ADR;
1001 prefixes |= PREFIX_FWAIT;
1013 static char op1out[100], op2out[100], op3out[100];
1014 static int op_address[3], op_ad, op_index[3];
1015 static int start_pc;
1019 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1020 * (see topic "Redundant prefixes" in the "Differences from 8086"
1021 * section of the "Virtual 8086 Mode" chapter.)
1022 * 'pc' should be the address of this instruction, it will
1023 * be used to print the target address if this is a relative jump or call
1024 * The function returns the length of this instruction in bytes.
1028 print_insn_i386 (pc, info)
1030 disassemble_info *info;
1034 int enter_instruction;
1035 char *first, *second, *third;
1037 unsigned char need_modrm;
1039 struct dis_private priv;
1040 bfd_byte *inbuf = priv.the_buffer;
1042 info->private_data = (PTR) &priv;
1043 priv.max_fetched = priv.the_buffer;
1044 priv.insn_start = pc;
1045 if (setjmp (priv.bailout) != 0)
1054 op_index[0] = op_index[1] = op_index[2] = -1;
1058 start_codep = inbuf;
1063 FETCH_DATA (info, codep + 1);
1065 enter_instruction = 1;
1067 enter_instruction = 0;
1071 if (prefixes & PREFIX_REPZ)
1073 if (prefixes & PREFIX_REPNZ)
1075 if (prefixes & PREFIX_LOCK)
1078 if ((prefixes & PREFIX_FWAIT)
1079 && ((*codep < 0xd8) || (*codep > 0xdf)))
1081 /* fwait not followed by floating point instruction */
1082 (*info->fprintf_func) (info->stream, "fwait");
1086 /* these would be initialized to 0 if disassembling for 8086 or 286 */
1090 if (prefixes & PREFIX_DATA)
1093 if (prefixes & PREFIX_ADR)
1096 oappend ("addr16 ");
1101 FETCH_DATA (info, codep + 2);
1102 dp = &dis386_twobyte[*++codep];
1103 need_modrm = twobyte_has_modrm[*codep];
1107 dp = &dis386[*codep];
1108 need_modrm = onebyte_has_modrm[*codep];
1114 FETCH_DATA (info, codep + 1);
1115 mod = (*codep >> 6) & 3;
1116 reg = (*codep >> 3) & 7;
1120 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1126 if (dp->name == NULL)
1127 dp = &grps[dp->bytemode1][reg];
1134 (*dp->op1)(dp->bytemode1);
1139 (*dp->op2)(dp->bytemode2);
1144 (*dp->op3)(dp->bytemode3);
1147 obufp = obuf + strlen (obuf);
1148 for (i = strlen (obuf); i < 6; i++)
1151 (*info->fprintf_func) (info->stream, "%s", obuf);
1153 /* enter instruction is printed with operands in the
1154 * same order as the intel book; everything else
1155 * is printed in reverse order
1157 if (enter_instruction)
1162 op_ad = op_index[0];
1163 op_index[0] = op_index[2];
1164 op_index[2] = op_ad;
1175 if (op_index[0] != -1)
1176 (*info->print_address_func) (op_address[op_index[0]], info);
1178 (*info->fprintf_func) (info->stream, "%s", first);
1184 (*info->fprintf_func) (info->stream, ",");
1185 if (op_index[1] != -1)
1186 (*info->print_address_func) (op_address[op_index[1]], info);
1188 (*info->fprintf_func) (info->stream, "%s", second);
1194 (*info->fprintf_func) (info->stream, ",");
1195 if (op_index[2] != -1)
1196 (*info->print_address_func) (op_address[op_index[2]], info);
1198 (*info->fprintf_func) (info->stream, "%s", third);
1200 return (codep - inbuf);
1203 char *float_mem[] = {
1279 #define STi OP_STi, 0
1280 int OP_ST(), OP_STi();
1282 #define FGRPd9_2 NULL, NULL, 0
1283 #define FGRPd9_4 NULL, NULL, 1
1284 #define FGRPd9_5 NULL, NULL, 2
1285 #define FGRPd9_6 NULL, NULL, 3
1286 #define FGRPd9_7 NULL, NULL, 4
1287 #define FGRPda_5 NULL, NULL, 5
1288 #define FGRPdb_4 NULL, NULL, 6
1289 #define FGRPde_3 NULL, NULL, 7
1290 #define FGRPdf_4 NULL, NULL, 8
1292 struct dis386 float_reg[][8] = {
1295 { "fadd", ST, STi },
1296 { "fmul", ST, STi },
1299 { "fsub", ST, STi },
1300 { "fsubr", ST, STi },
1301 { "fdiv", ST, STi },
1302 { "fdivr", ST, STi },
1317 { "fcmovb", ST, STi },
1318 { "fcmove", ST, STi },
1319 { "fcmovbe",ST, STi },
1320 { "fcmovu", ST, STi },
1328 { "fcmovnb",ST, STi },
1329 { "fcmovne",ST, STi },
1330 { "fcmovnbe",ST, STi },
1331 { "fcmovnu",ST, STi },
1333 { "fucomi", ST, STi },
1334 { "fcomi", ST, STi },
1339 { "fadd", STi, ST },
1340 { "fmul", STi, ST },
1343 { "fsub", STi, ST },
1344 { "fsubr", STi, ST },
1345 { "fdiv", STi, ST },
1346 { "fdivr", STi, ST },
1361 { "faddp", STi, ST },
1362 { "fmulp", STi, ST },
1365 { "fsubp", STi, ST },
1366 { "fsubrp", STi, ST },
1367 { "fdivp", STi, ST },
1368 { "fdivrp", STi, ST },
1377 { "fucomip",ST, STi },
1378 { "fcomip", ST, STi },
1384 char *fgrps[][8] = {
1387 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1392 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1397 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1402 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1407 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1412 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1417 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1418 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1423 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1428 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1436 unsigned char floatop;
1438 floatop = codep[-1];
1442 putop (float_mem[(floatop - 0xd8) * 8 + reg]);
1449 dp = &float_reg[floatop - 0xd8][reg];
1450 if (dp->name == NULL)
1452 putop (fgrps[dp->bytemode1][rm]);
1453 /* instruction fnstsw is only one with strange arg */
1455 && FETCH_DATA (the_info, codep + 1)
1457 strcpy (op1out, "%eax");
1464 (*dp->op1)(dp->bytemode1);
1467 (*dp->op2)(dp->bytemode2);
1485 sprintf (scratchbuf, "%%st(%d)", rm);
1486 oappend (scratchbuf);
1491 /* capital letters in template are macros */
1498 for (p = template; *p; p++)
1505 case 'C': /* For jcxz/jecxz */
1510 if ((prefixes & PREFIX_FWAIT) == 0)
1514 /* operand size flag */
1530 obufp += strlen (s);
1537 if (prefixes & PREFIX_CS)
1539 if (prefixes & PREFIX_DS)
1541 if (prefixes & PREFIX_SS)
1543 if (prefixes & PREFIX_ES)
1545 if (prefixes & PREFIX_FS)
1547 if (prefixes & PREFIX_GS)
1552 OP_indirE (bytemode)
1556 return OP_E (bytemode);
1565 /* skip mod/rm byte */
1573 oappend (names8[rm]);
1576 oappend (names16[rm]);
1580 oappend (names32[rm]);
1582 oappend (names16[rm]);
1585 oappend ("<bad dis table>");
1594 if (aflag) /* 32 bit address mode */
1609 FETCH_DATA (the_info, codep + 1);
1610 scale = (*codep >> 6) & 3;
1611 index = (*codep >> 3) & 7;
1626 FETCH_DATA (the_info, codep + 1);
1627 disp = *(char *)codep++;
1634 if (mod != 0 || base == 5)
1636 sprintf (scratchbuf, "0x%x", disp);
1637 oappend (scratchbuf);
1640 if (havebase || (havesib && (index != 4 || scale != 0)))
1644 oappend (names32[base]);
1649 sprintf (scratchbuf, ",%s", names32[index]);
1650 oappend (scratchbuf);
1652 sprintf (scratchbuf, ",%d", 1 << scale);
1653 oappend (scratchbuf);
1659 { /* 16 bit address mode */
1664 disp = (short) get16 ();
1667 FETCH_DATA (the_info, codep + 1);
1668 disp = *(char *)codep++;
1671 disp = (short) get16 ();
1675 if (mod != 0 || rm == 6)
1677 sprintf (scratchbuf, "0x%x", disp);
1678 oappend (scratchbuf);
1681 if (mod != 0 || rm != 6)
1684 oappend (index16[rm]);
1698 oappend (names8[reg]);
1701 oappend (names16[reg]);
1704 oappend (names32[reg]);
1708 oappend (names32[reg]);
1710 oappend (names16[reg]);
1713 oappend ("<internal disassembler error>");
1724 FETCH_DATA (the_info, codep + 4);
1725 x = *codep++ & 0xff;
1726 x |= (*codep++ & 0xff) << 8;
1727 x |= (*codep++ & 0xff) << 16;
1728 x |= (*codep++ & 0xff) << 24;
1737 FETCH_DATA (the_info, codep + 2);
1738 x = *codep++ & 0xff;
1739 x |= (*codep++ & 0xff) << 8;
1747 op_index[op_ad] = op_ad;
1748 op_address[op_ad] = op;
1759 case indir_dx_reg: s = "(%dx)"; break;
1760 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1761 case sp_reg: case bp_reg: case si_reg: case di_reg:
1762 s = names16[code - ax_reg];
1764 case es_reg: case ss_reg: case cs_reg:
1765 case ds_reg: case fs_reg: case gs_reg:
1766 s = names_seg[code - es_reg];
1768 case al_reg: case ah_reg: case cl_reg: case ch_reg:
1769 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1770 s = names8[code - al_reg];
1772 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1773 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1775 s = names32[code - eAX_reg];
1777 s = names16[code - eAX_reg];
1780 s = "<internal disassembler error>";
1796 FETCH_DATA (the_info, codep + 1);
1797 op = *codep++ & 0xff;
1809 oappend ("<internal disassembler error>");
1812 sprintf (scratchbuf, "$0x%x", op);
1813 oappend (scratchbuf);
1826 FETCH_DATA (the_info, codep + 1);
1827 op = *(char *)codep++;
1833 op = (short)get16();
1836 op = (short)get16 ();
1839 oappend ("<internal disassembler error>");
1842 sprintf (scratchbuf, "$0x%x", op);
1843 oappend (scratchbuf);
1857 FETCH_DATA (the_info, codep + 1);
1858 disp = *(char *)codep++;
1865 disp = (short)get16 ();
1866 /* for some reason, a data16 prefix on a jump instruction
1867 means that the pc is masked to 16 bits after the
1868 displacement is added! */
1873 oappend ("<internal disassembler error>");
1876 disp = (start_pc + codep - start_codep + disp) & mask;
1878 sprintf (scratchbuf, "0x%x", disp);
1879 oappend (scratchbuf);
1888 static char *sreg[] = {
1889 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1892 oappend (sreg[reg]);
1915 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1916 oappend (scratchbuf);
1922 offset = (short)get16 ();
1924 offset = start_pc + codep - start_codep + offset;
1926 sprintf (scratchbuf, "0x%x", offset);
1927 oappend (scratchbuf);
1930 oappend ("<internal disassembler error>");
1948 sprintf (scratchbuf, "0x%x", off);
1949 oappend (scratchbuf);
1959 oappend (aflag ? "%edi" : "%di");
1970 oappend (aflag ? "%esi" : "%si");
1989 codep++; /* skip mod/rm */
1990 sprintf (scratchbuf, "%%cr%d", reg);
1991 oappend (scratchbuf);
2000 codep++; /* skip mod/rm */
2001 sprintf (scratchbuf, "%%db%d", reg);
2002 oappend (scratchbuf);
2011 codep++; /* skip mod/rm */
2012 sprintf (scratchbuf, "%%tr%d", reg);
2013 oappend (scratchbuf);
2024 oappend (names32[rm]);
2027 oappend (names16[rm]);