Release 950109
[wine/multimedia.git] / debugger / opcodes / i386-dis.c
blob0d18311e6ae5f6f2edcc5fd96410bba1120daaaf
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 1989, 1991, 1993, 1994 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22 * July 1988
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.
35 #include "dis-asm.h"
36 #include "sysdep.h"
38 #define MAXLEN 20
40 #include <setjmp.h>
42 struct dis_private
44 /* Points to first byte not fetched. */
45 bfd_byte *max_fetched;
46 bfd_byte the_buffer[MAXLEN];
47 bfd_vma insn_start;
48 jmp_buf bailout;
51 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
52 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
53 on error. */
54 #define FETCH_DATA(info, addr) \
55 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
56 ? 1 : fetch_data ((info), (addr)))
58 static int
59 fetch_data (info, addr)
60 struct disassemble_info *info;
61 bfd_byte *addr;
63 int status;
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,
68 priv->max_fetched,
69 addr - priv->max_fetched,
70 info);
71 if (status != 0)
73 (*info->memory_error_func) (status, start, info);
74 longjmp (priv->bailout, 1);
76 else
77 priv->max_fetched = addr;
78 return 1;
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
88 #define M OP_E, 0
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 ();
150 #define b_mode 1
151 #define v_mode 2
152 #define w_mode 3
153 #define d_mode 4
155 #define es_reg 100
156 #define cs_reg 101
157 #define ss_reg 102
158 #define ds_reg 103
159 #define fs_reg 104
160 #define gs_reg 105
161 #define eAX_reg 107
162 #define eCX_reg 108
163 #define eDX_reg 109
164 #define eBX_reg 110
165 #define eSP_reg 111
166 #define eBP_reg 112
167 #define eSI_reg 113
168 #define eDI_reg 114
170 #define lptr 115
172 #define al_reg 116
173 #define cl_reg 117
174 #define dl_reg 118
175 #define bl_reg 119
176 #define ah_reg 120
177 #define ch_reg 121
178 #define dh_reg 122
179 #define bh_reg 123
181 #define ax_reg 124
182 #define cx_reg 125
183 #define dx_reg 126
184 #define bx_reg 127
185 #define sp_reg 128
186 #define bp_reg 129
187 #define si_reg 130
188 #define di_reg 131
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
209 #define FLOATCODE 50
210 #define FLOAT NULL, NULL, FLOATCODE
212 struct dis386 {
213 char *name;
214 int (*op1)();
215 int bytemode1;
216 int (*op2)();
217 int bytemode2;
218 int (*op3)();
219 int bytemode3;
222 struct dis386 dis386[] = {
223 /* 00 */
224 { "addb", Eb, Gb },
225 { "addS", Ev, Gv },
226 { "addb", Gb, Eb },
227 { "addS", Gv, Ev },
228 { "addb", AL, Ib },
229 { "addS", eAX, Iv },
230 { "pushl", es },
231 { "popl", es },
232 /* 08 */
233 { "orb", Eb, Gb },
234 { "orS", Ev, Gv },
235 { "orb", Gb, Eb },
236 { "orS", Gv, Ev },
237 { "orb", AL, Ib },
238 { "orS", eAX, Iv },
239 { "pushl", cs },
240 { "(bad)" }, /* 0x0f extended opcode escape */
241 /* 10 */
242 { "adcb", Eb, Gb },
243 { "adcS", Ev, Gv },
244 { "adcb", Gb, Eb },
245 { "adcS", Gv, Ev },
246 { "adcb", AL, Ib },
247 { "adcS", eAX, Iv },
248 { "pushl", ss },
249 { "popl", ss },
250 /* 18 */
251 { "sbbb", Eb, Gb },
252 { "sbbS", Ev, Gv },
253 { "sbbb", Gb, Eb },
254 { "sbbS", Gv, Ev },
255 { "sbbb", AL, Ib },
256 { "sbbS", eAX, Iv },
257 { "pushl", ds },
258 { "popl", ds },
259 /* 20 */
260 { "andb", Eb, Gb },
261 { "andS", Ev, Gv },
262 { "andb", Gb, Eb },
263 { "andS", Gv, Ev },
264 { "andb", AL, Ib },
265 { "andS", eAX, Iv },
266 { "(bad)" }, /* SEG ES prefix */
267 { "daa" },
268 /* 28 */
269 { "subb", Eb, Gb },
270 { "subS", Ev, Gv },
271 { "subb", Gb, Eb },
272 { "subS", Gv, Ev },
273 { "subb", AL, Ib },
274 { "subS", eAX, Iv },
275 { "(bad)" }, /* SEG CS prefix */
276 { "das" },
277 /* 30 */
278 { "xorb", Eb, Gb },
279 { "xorS", Ev, Gv },
280 { "xorb", Gb, Eb },
281 { "xorS", Gv, Ev },
282 { "xorb", AL, Ib },
283 { "xorS", eAX, Iv },
284 { "(bad)" }, /* SEG SS prefix */
285 { "aaa" },
286 /* 38 */
287 { "cmpb", Eb, Gb },
288 { "cmpS", Ev, Gv },
289 { "cmpb", Gb, Eb },
290 { "cmpS", Gv, Ev },
291 { "cmpb", AL, Ib },
292 { "cmpS", eAX, Iv },
293 { "(bad)" }, /* SEG DS prefix */
294 { "aas" },
295 /* 40 */
296 { "incS", eAX },
297 { "incS", eCX },
298 { "incS", eDX },
299 { "incS", eBX },
300 { "incS", eSP },
301 { "incS", eBP },
302 { "incS", eSI },
303 { "incS", eDI },
304 /* 48 */
305 { "decS", eAX },
306 { "decS", eCX },
307 { "decS", eDX },
308 { "decS", eBX },
309 { "decS", eSP },
310 { "decS", eBP },
311 { "decS", eSI },
312 { "decS", eDI },
313 /* 50 */
314 { "pushS", eAX },
315 { "pushS", eCX },
316 { "pushS", eDX },
317 { "pushS", eBX },
318 { "pushS", eSP },
319 { "pushS", eBP },
320 { "pushS", eSI },
321 { "pushS", eDI },
322 /* 58 */
323 { "popS", eAX },
324 { "popS", eCX },
325 { "popS", eDX },
326 { "popS", eBX },
327 { "popS", eSP },
328 { "popS", eBP },
329 { "popS", eSI },
330 { "popS", eDI },
331 /* 60 */
332 { "pusha" },
333 { "popa" },
334 { "boundS", Gv, Ma },
335 { "arpl", Ew, Gw },
336 { "(bad)" }, /* seg fs */
337 { "(bad)" }, /* seg gs */
338 { "(bad)" }, /* op size prefix */
339 { "(bad)" }, /* adr size prefix */
340 /* 68 */
341 { "pushS", Iv }, /* 386 book wrong */
342 { "imulS", Gv, Ev, Iv },
343 { "pushl", sIb }, /* push of byte really pushes 4 bytes */
344 { "imulS", Gv, Ev, Ib },
345 { "insb", Yb, indirDX },
346 { "insS", Yv, indirDX },
347 { "outsb", indirDX, Xb },
348 { "outsS", indirDX, Xv },
349 /* 70 */
350 { "jo", Jb },
351 { "jno", Jb },
352 { "jb", Jb },
353 { "jae", Jb },
354 { "je", Jb },
355 { "jne", Jb },
356 { "jbe", Jb },
357 { "ja", Jb },
358 /* 78 */
359 { "js", Jb },
360 { "jns", Jb },
361 { "jp", Jb },
362 { "jnp", Jb },
363 { "jl", Jb },
364 { "jnl", Jb },
365 { "jle", Jb },
366 { "jg", Jb },
367 /* 80 */
368 { GRP1b },
369 { GRP1S },
370 { "(bad)" },
371 { GRP1Ss },
372 { "testb", Eb, Gb },
373 { "testS", Ev, Gv },
374 { "xchgb", Eb, Gb },
375 { "xchgS", Ev, Gv },
376 /* 88 */
377 { "movb", Eb, Gb },
378 { "movS", Ev, Gv },
379 { "movb", Gb, Eb },
380 { "movS", Gv, Ev },
381 { "movw", Ew, Sw },
382 { "leaS", Gv, M },
383 { "movw", Sw, Ew },
384 { "popS", Ev },
385 /* 90 */
386 { "nop" },
387 { "xchgS", eCX, eAX },
388 { "xchgS", eDX, eAX },
389 { "xchgS", eBX, eAX },
390 { "xchgS", eSP, eAX },
391 { "xchgS", eBP, eAX },
392 { "xchgS", eSI, eAX },
393 { "xchgS", eDI, eAX },
394 /* 98 */
395 { "cwtl" },
396 { "cltd" },
397 { "lcall", Ap },
398 { "(bad)" }, /* fwait */
399 { "pushf" },
400 { "popf" },
401 { "sahf" },
402 { "lahf" },
403 /* a0 */
404 { "movb", AL, Ob },
405 { "movS", eAX, Ov },
406 { "movb", Ob, AL },
407 { "movS", Ov, eAX },
408 { "movsb", Yb, Xb },
409 { "movsS", Yv, Xv },
410 { "cmpsb", Yb, Xb },
411 { "cmpsS", Yv, Xv },
412 /* a8 */
413 { "testb", AL, Ib },
414 { "testS", eAX, Iv },
415 { "stosb", Yb, AL },
416 { "stosS", Yv, eAX },
417 { "lodsb", AL, Xb },
418 { "lodsS", eAX, Xv },
419 { "scasb", AL, Yb },
420 { "scasS", eAX, Yv },
421 /* b0 */
422 { "movb", AL, Ib },
423 { "movb", CL, Ib },
424 { "movb", DL, Ib },
425 { "movb", BL, Ib },
426 { "movb", AH, Ib },
427 { "movb", CH, Ib },
428 { "movb", DH, Ib },
429 { "movb", BH, Ib },
430 /* b8 */
431 { "movS", eAX, Iv },
432 { "movS", eCX, Iv },
433 { "movS", eDX, Iv },
434 { "movS", eBX, Iv },
435 { "movS", eSP, Iv },
436 { "movS", eBP, Iv },
437 { "movS", eSI, Iv },
438 { "movS", eDI, Iv },
439 /* c0 */
440 { GRP2b },
441 { GRP2S },
442 { "ret", Iw },
443 { "ret" },
444 { "lesS", Gv, Mp },
445 { "ldsS", Gv, Mp },
446 { "movb", Eb, Ib },
447 { "movS", Ev, Iv },
448 /* c8 */
449 { "enter", Iw, Ib },
450 { "leave" },
451 { "lret", Iw },
452 { "lret" },
453 { "int3" },
454 { "int", Ib },
455 { "into" },
456 { "iret" },
457 /* d0 */
458 { GRP2b_one },
459 { GRP2S_one },
460 { GRP2b_cl },
461 { GRP2S_cl },
462 { "aam", Ib },
463 { "aad", Ib },
464 { "(bad)" },
465 { "xlat" },
466 /* d8 */
467 { FLOAT },
468 { FLOAT },
469 { FLOAT },
470 { FLOAT },
471 { FLOAT },
472 { FLOAT },
473 { FLOAT },
474 { FLOAT },
475 /* e0 */
476 { "loopne", Jb },
477 { "loope", Jb },
478 { "loop", Jb },
479 { "jCcxz", Jb },
480 { "inb", AL, Ib },
481 { "inS", eAX, Ib },
482 { "outb", Ib, AL },
483 { "outS", Ib, eAX },
484 /* e8 */
485 { "call", Av },
486 { "jmp", Jv },
487 { "ljmp", Ap },
488 { "jmp", Jb },
489 { "inb", AL, indirDX },
490 { "inS", eAX, indirDX },
491 { "outb", indirDX, AL },
492 { "outS", indirDX, eAX },
493 /* f0 */
494 { "(bad)" }, /* lock prefix */
495 { "(bad)" },
496 { "(bad)" }, /* repne */
497 { "(bad)" }, /* repz */
498 { "hlt" },
499 { "cmc" },
500 { GRP3b },
501 { GRP3S },
502 /* f8 */
503 { "clc" },
504 { "stc" },
505 { "cli" },
506 { "sti" },
507 { "cld" },
508 { "std" },
509 { GRP4 },
510 { GRP5 },
513 struct dis386 dis386_twobyte[] = {
514 /* 00 */
515 { GRP6 },
516 { GRP7 },
517 { "larS", Gv, Ew },
518 { "lslS", Gv, Ew },
519 { "(bad)" },
520 { "(bad)" },
521 { "clts" },
522 { "(bad)" },
523 /* 08 */
524 { "invd" },
525 { "wbinvd" },
526 { "(bad)" }, { "(bad)" },
527 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
528 /* 10 */
529 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
530 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
531 /* 18 */
532 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
533 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
534 /* 20 */
535 /* these are all backward in appendix A of the intel book */
536 { "movl", Rd, Cd },
537 { "movl", Rd, Dd },
538 { "movl", Cd, Rd },
539 { "movl", Dd, Rd },
540 { "movl", Rd, Td },
541 { "(bad)" },
542 { "movl", Td, Rd },
543 { "(bad)" },
544 /* 28 */
545 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
546 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
547 /* 30 */
548 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
549 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
550 /* 38 */
551 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
552 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
553 /* 40 */
554 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
555 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
556 /* 48 */
557 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
558 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
559 /* 50 */
560 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
561 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
562 /* 58 */
563 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
564 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
565 /* 60 */
566 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
567 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
568 /* 68 */
569 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
570 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
571 /* 70 */
572 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
573 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
574 /* 78 */
575 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
576 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
577 /* 80 */
578 { "jo", Jv },
579 { "jno", Jv },
580 { "jb", Jv },
581 { "jae", Jv },
582 { "je", Jv },
583 { "jne", Jv },
584 { "jbe", Jv },
585 { "ja", Jv },
586 /* 88 */
587 { "js", Jv },
588 { "jns", Jv },
589 { "jp", Jv },
590 { "jnp", Jv },
591 { "jl", Jv },
592 { "jge", Jv },
593 { "jle", Jv },
594 { "jg", Jv },
595 /* 90 */
596 { "seto", Eb },
597 { "setno", Eb },
598 { "setb", Eb },
599 { "setae", Eb },
600 { "sete", Eb },
601 { "setne", Eb },
602 { "setbe", Eb },
603 { "seta", Eb },
604 /* 98 */
605 { "sets", Eb },
606 { "setns", Eb },
607 { "setp", Eb },
608 { "setnp", Eb },
609 { "setl", Eb },
610 { "setge", Eb },
611 { "setle", Eb },
612 { "setg", Eb },
613 /* a0 */
614 { "pushl", fs },
615 { "popl", fs },
616 { "(bad)" },
617 { "btS", Ev, Gv },
618 { "shldS", Ev, Gv, Ib },
619 { "shldS", Ev, Gv, CL },
620 { "(bad)" },
621 { "(bad)" },
622 /* a8 */
623 { "pushl", gs },
624 { "popl", gs },
625 { "(bad)" },
626 { "btsS", Ev, Gv },
627 { "shrdS", Ev, Gv, Ib },
628 { "shrdS", Ev, Gv, CL },
629 { "(bad)" },
630 { "imulS", Gv, Ev },
631 /* b0 */
632 { "cmpxchgb", Eb, Gb },
633 { "cmpxchgS", Ev, Gv },
634 { "lssS", Gv, Mp }, /* 386 lists only Mp */
635 { "btrS", Ev, Gv },
636 { "lfsS", Gv, Mp }, /* 386 lists only Mp */
637 { "lgsS", Gv, Mp }, /* 386 lists only Mp */
638 { "movzbS", Gv, Eb },
639 { "movzwS", Gv, Ew },
640 /* b8 */
641 { "(bad)" },
642 { "(bad)" },
643 { GRP8 },
644 { "btcS", Ev, Gv },
645 { "bsfS", Gv, Ev },
646 { "bsrS", Gv, Ev },
647 { "movsbS", Gv, Eb },
648 { "movswS", Gv, Ew },
649 /* c0 */
650 { "xaddb", Eb, Gb },
651 { "xaddS", Ev, Gv },
652 { "(bad)" }, { "(bad)" },
653 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
654 /* c8 */
655 { "bswap", eAX },
656 { "bswap", eCX },
657 { "bswap", eDX },
658 { "bswap", eBX },
659 { "bswap", eSP },
660 { "bswap", eBP },
661 { "bswap", eSI },
662 { "bswap", eDI },
663 /* d0 */
664 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
665 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
666 /* d8 */
667 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
668 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
669 /* e0 */
670 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
671 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
672 /* e8 */
673 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
674 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
675 /* f0 */
676 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
677 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
678 /* f8 */
679 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
680 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
683 static char obuf[100];
684 static char *obufp;
685 static char scratchbuf[100];
686 static unsigned char *start_codep;
687 static unsigned char *codep;
688 static disassemble_info *the_info;
689 static int mod;
690 static int rm;
691 static int reg;
692 static void oappend ();
694 static char *names32[]={
695 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
697 static char *names16[] = {
698 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
700 static char *names8[] = {
701 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
703 static char *names_seg[] = {
704 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
706 static char *names_rmw[] = {
707 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx",
710 struct dis386 grps[][8] = {
711 /* GRP1b */
713 { "addb", Eb, Ib },
714 { "orb", Eb, Ib },
715 { "adcb", Eb, Ib },
716 { "sbbb", Eb, Ib },
717 { "andb", Eb, Ib },
718 { "subb", Eb, Ib },
719 { "xorb", Eb, Ib },
720 { "cmpb", Eb, Ib }
722 /* GRP1S */
724 { "addS", Ev, Iv },
725 { "orS", Ev, Iv },
726 { "adcS", Ev, Iv },
727 { "sbbS", Ev, Iv },
728 { "andS", Ev, Iv },
729 { "subS", Ev, Iv },
730 { "xorS", Ev, Iv },
731 { "cmpS", Ev, Iv }
733 /* GRP1Ss */
735 { "addS", Ev, sIb },
736 { "orS", Ev, sIb },
737 { "adcS", Ev, sIb },
738 { "sbbS", Ev, sIb },
739 { "andS", Ev, sIb },
740 { "subS", Ev, sIb },
741 { "xorS", Ev, sIb },
742 { "cmpS", Ev, sIb }
744 /* GRP2b */
746 { "rolb", Eb, Ib },
747 { "rorb", Eb, Ib },
748 { "rclb", Eb, Ib },
749 { "rcrb", Eb, Ib },
750 { "shlb", Eb, Ib },
751 { "shrb", Eb, Ib },
752 { "(bad)" },
753 { "sarb", Eb, Ib },
755 /* GRP2S */
757 { "rolS", Ev, Ib },
758 { "rorS", Ev, Ib },
759 { "rclS", Ev, Ib },
760 { "rcrS", Ev, Ib },
761 { "shlS", Ev, Ib },
762 { "shrS", Ev, Ib },
763 { "(bad)" },
764 { "sarS", Ev, Ib },
766 /* GRP2b_one */
768 { "rolb", Eb },
769 { "rorb", Eb },
770 { "rclb", Eb },
771 { "rcrb", Eb },
772 { "shlb", Eb },
773 { "shrb", Eb },
774 { "(bad)" },
775 { "sarb", Eb },
777 /* GRP2S_one */
779 { "rolS", Ev },
780 { "rorS", Ev },
781 { "rclS", Ev },
782 { "rcrS", Ev },
783 { "shlS", Ev },
784 { "shrS", Ev },
785 { "(bad)" },
786 { "sarS", Ev },
788 /* GRP2b_cl */
790 { "rolb", Eb, CL },
791 { "rorb", Eb, CL },
792 { "rclb", Eb, CL },
793 { "rcrb", Eb, CL },
794 { "shlb", Eb, CL },
795 { "shrb", Eb, CL },
796 { "(bad)" },
797 { "sarb", Eb, CL },
799 /* GRP2S_cl */
801 { "rolS", Ev, CL },
802 { "rorS", Ev, CL },
803 { "rclS", Ev, CL },
804 { "rcrS", Ev, CL },
805 { "shlS", Ev, CL },
806 { "shrS", Ev, CL },
807 { "(bad)" },
808 { "sarS", Ev, CL }
810 /* GRP3b */
812 { "testb", Eb, Ib },
813 { "(bad)", Eb },
814 { "notb", Eb },
815 { "negb", Eb },
816 { "mulb", AL, Eb },
817 { "imulb", AL, Eb },
818 { "divb", AL, Eb },
819 { "idivb", AL, Eb }
821 /* GRP3S */
823 { "testS", Ev, Iv },
824 { "(bad)" },
825 { "notS", Ev },
826 { "negS", Ev },
827 { "mulS", eAX, Ev },
828 { "imulS", eAX, Ev },
829 { "divS", eAX, Ev },
830 { "idivS", eAX, Ev },
832 /* GRP4 */
834 { "incb", Eb },
835 { "decb", Eb },
836 { "(bad)" },
837 { "(bad)" },
838 { "(bad)" },
839 { "(bad)" },
840 { "(bad)" },
841 { "(bad)" },
843 /* GRP5 */
845 { "incS", Ev },
846 { "decS", Ev },
847 { "call", indirEv },
848 { "lcall", indirEv },
849 { "jmp", indirEv },
850 { "ljmp", indirEv },
851 { "pushS", Ev },
852 { "(bad)" },
854 /* GRP6 */
856 { "sldt", Ew },
857 { "str", Ew },
858 { "lldt", Ew },
859 { "ltr", Ew },
860 { "verr", Ew },
861 { "verw", Ew },
862 { "(bad)" },
863 { "(bad)" }
865 /* GRP7 */
867 { "sgdt", Ew },
868 { "sidt", Ew },
869 { "lgdt", Ew },
870 { "lidt", Ew },
871 { "smsw", Ew },
872 { "(bad)" },
873 { "lmsw", Ew },
874 { "invlpg", Ew },
876 /* GRP8 */
878 { "(bad)" },
879 { "(bad)" },
880 { "(bad)" },
881 { "(bad)" },
882 { "btS", Ev, Ib },
883 { "btsS", Ev, Ib },
884 { "btrS", Ev, Ib },
885 { "btcS", Ev, Ib },
889 #define PREFIX_REPZ 1
890 #define PREFIX_REPNZ 2
891 #define PREFIX_LOCK 4
892 #define PREFIX_CS 8
893 #define PREFIX_SS 0x10
894 #define PREFIX_DS 0x20
895 #define PREFIX_ES 0x40
896 #define PREFIX_FS 0x80
897 #define PREFIX_GS 0x100
898 #define PREFIX_DATA 0x200
899 #define PREFIX_ADR 0x400
900 #define PREFIX_FWAIT 0x800
902 static int prefixes;
904 static void
905 ckprefix ()
907 prefixes = 0;
908 while (1)
910 FETCH_DATA (the_info, codep + 1);
911 switch (*codep)
913 case 0xf3:
914 prefixes |= PREFIX_REPZ;
915 break;
916 case 0xf2:
917 prefixes |= PREFIX_REPNZ;
918 break;
919 case 0xf0:
920 prefixes |= PREFIX_LOCK;
921 break;
922 case 0x2e:
923 prefixes |= PREFIX_CS;
924 break;
925 case 0x36:
926 prefixes |= PREFIX_SS;
927 break;
928 case 0x3e:
929 prefixes |= PREFIX_DS;
930 break;
931 case 0x26:
932 prefixes |= PREFIX_ES;
933 break;
934 case 0x64:
935 prefixes |= PREFIX_FS;
936 break;
937 case 0x65:
938 prefixes |= PREFIX_GS;
939 break;
940 case 0x66:
941 prefixes |= PREFIX_DATA;
942 break;
943 case 0x67:
944 prefixes |= PREFIX_ADR;
945 break;
946 case 0x9b:
947 prefixes |= PREFIX_FWAIT;
948 break;
949 default:
950 return;
952 codep++;
956 static int machine;
957 static int dflag;
958 static int aflag;
960 static char op1out[100], op2out[100], op3out[100];
961 static int op_address[3], op_ad, op_index[3];
962 static int start_pc;
966 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
967 * (see topic "Redundant prefixes" in the "Differences from 8086"
968 * section of the "Virtual 8086 Mode" chapter.)
969 * 'pc' should be the address of this instruction, it will
970 * be used to print the target address if this is a relative jump or call
971 * The function returns the length of this instruction in bytes.
973 static int
974 print_insn_i286_or_i386 (pc, info)
975 bfd_vma pc;
976 disassemble_info *info;
978 struct dis386 *dp;
979 int i;
980 int enter_instruction;
981 char *first, *second, *third;
982 int needcomma;
984 struct dis_private priv;
985 bfd_byte *inbuf = priv.the_buffer;
987 info->private_data = (PTR) &priv;
988 priv.max_fetched = priv.the_buffer;
989 priv.insn_start = pc;
990 if (setjmp (priv.bailout) != 0)
991 /* Error return. */
992 return -1;
994 obuf[0] = 0;
995 op1out[0] = 0;
996 op2out[0] = 0;
997 op3out[0] = 0;
999 op_index[0] = op_index[1] = op_index[2] = -1;
1001 the_info = info;
1002 start_pc = pc;
1003 start_codep = inbuf;
1004 codep = inbuf;
1006 ckprefix ();
1008 FETCH_DATA (info, codep + 1);
1009 if (*codep == 0xc8)
1010 enter_instruction = 1;
1011 else
1012 enter_instruction = 0;
1014 obufp = obuf;
1016 if (prefixes & PREFIX_REPZ)
1017 oappend ("repz ");
1018 if (prefixes & PREFIX_REPNZ)
1019 oappend ("repnz ");
1020 if (prefixes & PREFIX_LOCK)
1021 oappend ("lock ");
1023 if ((prefixes & PREFIX_FWAIT)
1024 && ((*codep < 0xd8) || (*codep > 0xdf)))
1026 /* fwait not followed by floating point instruction */
1027 (*info->fprintf_func) (info->stream, "fwait");
1028 return (1);
1031 if (prefixes & PREFIX_DATA)
1032 dflag ^= 1;
1034 if (prefixes & PREFIX_ADR)
1036 aflag ^= 1;
1037 oappend ("addr16 ");
1040 if (*codep == 0x0f)
1042 FETCH_DATA (info, codep + 2);
1043 dp = &dis386_twobyte[*++codep];
1045 else
1046 dp = &dis386[*codep];
1047 codep++;
1049 /* Fetch the mod/reg/rm byte. FIXME: We should be only fetching
1050 this if we need it. As it is, this code loses if there is a
1051 one-byte instruction (without a mod/reg/rm byte) at the end of
1052 the address space. */
1054 FETCH_DATA (info, codep + 1);
1055 mod = (*codep >> 6) & 3;
1056 reg = (*codep >> 3) & 7;
1057 rm = *codep & 7;
1059 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1061 dofloat ();
1063 else
1065 if (dp->name == NULL)
1066 dp = &grps[dp->bytemode1][reg];
1068 putop (dp->name);
1070 obufp = op1out;
1071 op_ad = 2;
1072 if (dp->op1)
1073 (*dp->op1)(dp->bytemode1);
1075 obufp = op2out;
1076 op_ad = 1;
1077 if (dp->op2)
1078 (*dp->op2)(dp->bytemode2);
1080 obufp = op3out;
1081 op_ad = 0;
1082 if (dp->op3)
1083 (*dp->op3)(dp->bytemode3);
1086 obufp = obuf + strlen (obuf);
1087 for (i = strlen (obuf); i < 6; i++)
1088 oappend (" ");
1089 oappend (" ");
1090 (*info->fprintf_func) (info->stream, "%s", obuf);
1092 /* enter instruction is printed with operands in the
1093 * same order as the intel book; everything else
1094 * is printed in reverse order
1096 if (enter_instruction)
1098 first = op1out;
1099 second = op2out;
1100 third = op3out;
1101 op_ad = op_index[0];
1102 op_index[0] = op_index[2];
1103 op_index[2] = op_ad;
1105 else
1107 first = op3out;
1108 second = op2out;
1109 third = op1out;
1111 needcomma = 0;
1112 if (*first)
1114 if (op_index[0] != -1)
1115 (*info->print_address_func) (op_address[op_index[0]], info);
1116 else
1117 (*info->fprintf_func) (info->stream, "%s", first);
1118 needcomma = 1;
1120 if (*second)
1122 if (needcomma)
1123 (*info->fprintf_func) (info->stream, ",");
1124 if (op_index[1] != -1)
1125 (*info->print_address_func) (op_address[op_index[1]], info);
1126 else
1127 (*info->fprintf_func) (info->stream, "%s", second);
1128 needcomma = 1;
1130 if (*third)
1132 if (needcomma)
1133 (*info->fprintf_func) (info->stream, ",");
1134 if (op_index[2] != -1)
1135 (*info->print_address_func) (op_address[op_index[2]], info);
1136 else
1137 (*info->fprintf_func) (info->stream, "%s", third);
1139 return (codep - inbuf);
1143 print_insn_i286 (pc, info)
1144 bfd_vma pc;
1145 disassemble_info *info;
1147 machine = 286;
1148 dflag = 0;
1149 aflag = 0;
1150 return print_insn_i286_or_i386 (pc, info);
1154 print_insn_i386 (pc, info)
1155 bfd_vma pc;
1156 disassemble_info *info;
1158 machine = 386;
1159 dflag = 1;
1160 aflag = 1;
1161 return print_insn_i286_or_i386 (pc, info, 36);
1164 char *float_mem[] = {
1165 /* d8 */
1166 "fadds",
1167 "fmuls",
1168 "fcoms",
1169 "fcomps",
1170 "fsubs",
1171 "fsubrs",
1172 "fdivs",
1173 "fdivrs",
1174 /* d9 */
1175 "flds",
1176 "(bad)",
1177 "fsts",
1178 "fstps",
1179 "fldenv",
1180 "fldcw",
1181 "fNstenv",
1182 "fNstcw",
1183 /* da */
1184 "fiaddl",
1185 "fimull",
1186 "ficoml",
1187 "ficompl",
1188 "fisubl",
1189 "fisubrl",
1190 "fidivl",
1191 "fidivrl",
1192 /* db */
1193 "fildl",
1194 "(bad)",
1195 "fistl",
1196 "fistpl",
1197 "(bad)",
1198 "fldt",
1199 "(bad)",
1200 "fstpt",
1201 /* dc */
1202 "faddl",
1203 "fmull",
1204 "fcoml",
1205 "fcompl",
1206 "fsubl",
1207 "fsubrl",
1208 "fdivl",
1209 "fdivrl",
1210 /* dd */
1211 "fldl",
1212 "(bad)",
1213 "fstl",
1214 "fstpl",
1215 "frstor",
1216 "(bad)",
1217 "fNsave",
1218 "fNstsw",
1219 /* de */
1220 "fiadd",
1221 "fimul",
1222 "ficom",
1223 "ficomp",
1224 "fisub",
1225 "fisubr",
1226 "fidiv",
1227 "fidivr",
1228 /* df */
1229 "fild",
1230 "(bad)",
1231 "fist",
1232 "fistp",
1233 "fbld",
1234 "fildll",
1235 "fbstp",
1236 "fistpll",
1239 #define ST OP_ST, 0
1240 #define STi OP_STi, 0
1241 int OP_ST(), OP_STi();
1243 #define FGRPd9_2 NULL, NULL, 0
1244 #define FGRPd9_4 NULL, NULL, 1
1245 #define FGRPd9_5 NULL, NULL, 2
1246 #define FGRPd9_6 NULL, NULL, 3
1247 #define FGRPd9_7 NULL, NULL, 4
1248 #define FGRPda_5 NULL, NULL, 5
1249 #define FGRPdb_4 NULL, NULL, 6
1250 #define FGRPde_3 NULL, NULL, 7
1251 #define FGRPdf_4 NULL, NULL, 8
1253 struct dis386 float_reg[][8] = {
1254 /* d8 */
1256 { "fadd", ST, STi },
1257 { "fmul", ST, STi },
1258 { "fcom", STi },
1259 { "fcomp", STi },
1260 { "fsub", ST, STi },
1261 { "fsubr", ST, STi },
1262 { "fdiv", ST, STi },
1263 { "fdivr", ST, STi },
1265 /* d9 */
1267 { "fld", STi },
1268 { "fxch", STi },
1269 { FGRPd9_2 },
1270 { "(bad)" },
1271 { FGRPd9_4 },
1272 { FGRPd9_5 },
1273 { FGRPd9_6 },
1274 { FGRPd9_7 },
1276 /* da */
1278 { "(bad)" },
1279 { "(bad)" },
1280 { "(bad)" },
1281 { "(bad)" },
1282 { "(bad)" },
1283 { FGRPda_5 },
1284 { "(bad)" },
1285 { "(bad)" },
1287 /* db */
1289 { "(bad)" },
1290 { "(bad)" },
1291 { "(bad)" },
1292 { "(bad)" },
1293 { FGRPdb_4 },
1294 { "(bad)" },
1295 { "(bad)" },
1296 { "(bad)" },
1298 /* dc */
1300 { "fadd", STi, ST },
1301 { "fmul", STi, ST },
1302 { "(bad)" },
1303 { "(bad)" },
1304 { "fsub", STi, ST },
1305 { "fsubr", STi, ST },
1306 { "fdiv", STi, ST },
1307 { "fdivr", STi, ST },
1309 /* dd */
1311 { "ffree", STi },
1312 { "(bad)" },
1313 { "fst", STi },
1314 { "fstp", STi },
1315 { "fucom", STi },
1316 { "fucomp", STi },
1317 { "(bad)" },
1318 { "(bad)" },
1320 /* de */
1322 { "faddp", STi, ST },
1323 { "fmulp", STi, ST },
1324 { "(bad)" },
1325 { FGRPde_3 },
1326 { "fsubp", STi, ST },
1327 { "fsubrp", STi, ST },
1328 { "fdivp", STi, ST },
1329 { "fdivrp", STi, ST },
1331 /* df */
1333 { "(bad)" },
1334 { "(bad)" },
1335 { "(bad)" },
1336 { "(bad)" },
1337 { FGRPdf_4 },
1338 { "(bad)" },
1339 { "(bad)" },
1340 { "(bad)" },
1345 char *fgrps[][8] = {
1346 /* d9_2 0 */
1348 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1351 /* d9_4 1 */
1353 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1356 /* d9_5 2 */
1358 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1361 /* d9_6 3 */
1363 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1366 /* d9_7 4 */
1368 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1371 /* da_5 5 */
1373 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1376 /* db_4 6 */
1378 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1379 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1382 /* de_3 7 */
1384 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1387 /* df_4 8 */
1389 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1393 static void
1394 dofloat ()
1396 struct dis386 *dp;
1397 unsigned char floatop;
1399 floatop = codep[-1];
1401 if (mod != 3)
1403 putop (float_mem[(floatop - 0xd8) * 8 + reg]);
1404 obufp = op1out;
1405 OP_E (v_mode);
1406 return;
1408 codep++;
1410 dp = &float_reg[floatop - 0xd8][reg];
1411 if (dp->name == NULL)
1413 putop (fgrps[dp->bytemode1][rm]);
1414 /* instruction fnstsw is only one with strange arg */
1415 if (floatop == 0xdf
1416 && FETCH_DATA (the_info, codep + 1)
1417 && *codep == 0xe0)
1418 strcpy (op1out, "%eax");
1420 else
1422 putop (dp->name);
1423 obufp = op1out;
1424 if (dp->op1)
1425 (*dp->op1)(dp->bytemode1);
1426 obufp = op2out;
1427 if (dp->op2)
1428 (*dp->op2)(dp->bytemode2);
1432 /* ARGSUSED */
1434 OP_ST (ignore)
1435 int ignore;
1437 oappend ("%st");
1438 return (0);
1441 /* ARGSUSED */
1443 OP_STi (ignore)
1444 int ignore;
1446 sprintf (scratchbuf, "%%st(%d)", rm);
1447 oappend (scratchbuf);
1448 return (0);
1452 /* capital letters in template are macros */
1453 static void
1454 putop (template)
1455 char *template;
1457 char *p;
1459 for (p = template; *p; p++)
1461 switch (*p)
1463 default:
1464 *obufp++ = *p;
1465 break;
1466 case 'C': /* For jcxz/jecxz */
1467 if (aflag == 0)
1468 *obufp++ = 'e';
1469 break;
1470 case 'N':
1471 if ((prefixes & PREFIX_FWAIT) == 0)
1472 *obufp++ = 'n';
1473 break;
1474 case 'S':
1475 /* operand size flag */
1476 if (dflag)
1477 *obufp++ = 'l';
1478 else
1479 *obufp++ = 'w';
1480 break;
1483 *obufp = 0;
1486 static void
1487 oappend (s)
1488 char *s;
1490 strcpy (obufp, s);
1491 obufp += strlen (s);
1492 *obufp = 0;
1495 static void
1496 append_prefix ()
1498 if (prefixes & PREFIX_CS)
1499 oappend ("%cs:");
1500 if (prefixes & PREFIX_DS)
1501 oappend ("%ds:");
1502 if (prefixes & PREFIX_SS)
1503 oappend ("%ss:");
1504 if (prefixes & PREFIX_ES)
1505 oappend ("%es:");
1506 if (prefixes & PREFIX_FS)
1507 oappend ("%fs:");
1508 if (prefixes & PREFIX_GS)
1509 oappend ("%gs:");
1513 OP_indirE (bytemode)
1514 int bytemode;
1516 oappend ("*");
1517 OP_E (bytemode);
1518 return (0);
1522 OP_E (bytemode)
1523 int bytemode;
1525 int disp;
1526 int havesib;
1527 int base;
1528 int index;
1529 int scale;
1530 int havebase;
1532 /* skip mod/rm byte */
1533 codep++;
1535 havesib = 0;
1536 havebase = 0;
1537 disp = 0;
1539 if (mod == 3)
1541 switch (bytemode)
1543 case b_mode:
1544 oappend (names8[rm]);
1545 break;
1546 case w_mode:
1547 oappend (names16[rm]);
1548 break;
1549 case v_mode:
1550 if (dflag)
1551 oappend (names32[rm]);
1552 else
1553 oappend (names16[rm]);
1554 break;
1555 default:
1556 oappend ("<bad dis table>");
1557 break;
1559 return (0);
1562 append_prefix ();
1564 if (machine == 286)
1566 if (mod == 0 && rm == 6)
1568 sprintf (scratchbuf, "0x%04x", get16 ());
1569 oappend (scratchbuf);
1570 return 0;
1573 if (mod == 1)
1575 FETCH_DATA (the_info, codep + 1);
1576 disp = *(char *)codep++;
1578 else if (mod == 2)
1579 disp = get16 ();
1580 else
1581 disp = 0;
1582 if (disp != 0)
1584 sprintf (scratchbuf, "0x%x", disp & 0xffff);
1585 oappend (scratchbuf);
1588 sprintf (scratchbuf, "(%s)", names_rmw[rm]);
1589 oappend (scratchbuf);
1590 return 0;
1593 if (rm == 4)
1595 havesib = 1;
1596 havebase = 1;
1597 FETCH_DATA (the_info, codep + 1);
1598 scale = (*codep >> 6) & 3;
1599 index = (*codep >> 3) & 7;
1600 base = *codep & 7;
1601 codep++;
1604 switch (mod)
1606 case 0:
1607 switch (rm)
1609 case 4:
1610 /* implies havesib and havebase */
1611 if (base == 5) {
1612 havebase = 0;
1613 disp = get32 ();
1615 break;
1616 case 5:
1617 disp = get32 ();
1618 break;
1619 default:
1620 havebase = 1;
1621 base = rm;
1622 break;
1624 break;
1625 case 1:
1626 FETCH_DATA (the_info, codep + 1);
1627 disp = *(char *)codep++;
1628 if (rm != 4)
1630 havebase = 1;
1631 base = rm;
1633 break;
1634 case 2:
1635 disp = get32 ();
1636 if (rm != 4)
1638 havebase = 1;
1639 base = rm;
1641 break;
1644 if (mod != 0 || rm == 5 || (havesib && base == 5))
1646 sprintf (scratchbuf, "0x%x", disp);
1647 oappend (scratchbuf);
1650 if (havebase || havesib)
1652 oappend ("(");
1653 if (havebase)
1654 oappend (names32[base]);
1655 if (havesib)
1657 if (index != 4)
1659 sprintf (scratchbuf, ",%s", names32[index]);
1660 oappend (scratchbuf);
1662 sprintf (scratchbuf, ",%d", 1 << scale);
1663 oappend (scratchbuf);
1665 oappend (")");
1667 return (0);
1671 OP_G (bytemode)
1672 int bytemode;
1674 switch (bytemode)
1676 case b_mode:
1677 oappend (names8[reg]);
1678 break;
1679 case w_mode:
1680 oappend (names16[reg]);
1681 break;
1682 case d_mode:
1683 oappend (names32[reg]);
1684 break;
1685 case v_mode:
1686 if (dflag)
1687 oappend (names32[reg]);
1688 else
1689 oappend (names16[reg]);
1690 break;
1691 default:
1692 oappend ("<internal disassembler error>");
1693 break;
1695 return (0);
1698 static int
1699 get32 ()
1701 int x = 0;
1703 FETCH_DATA (the_info, codep + 4);
1704 x = *codep++ & 0xff;
1705 x |= (*codep++ & 0xff) << 8;
1706 x |= (*codep++ & 0xff) << 16;
1707 x |= (*codep++ & 0xff) << 24;
1708 return (x);
1711 static int
1712 get16 ()
1714 int x = 0;
1716 FETCH_DATA (the_info, codep + 2);
1717 x = *codep++ & 0xff;
1718 x |= (*codep++ & 0xff) << 8;
1719 return (x);
1722 static void
1723 set_op (op)
1724 int op;
1726 op_index[op_ad] = op_ad;
1727 op_address[op_ad] = op;
1731 OP_REG (code)
1732 int code;
1734 char *s;
1736 switch (code)
1738 case indir_dx_reg: s = "(%dx)"; break;
1739 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1740 case sp_reg: case bp_reg: case si_reg: case di_reg:
1741 s = names16[code - ax_reg];
1742 break;
1743 case es_reg: case ss_reg: case cs_reg:
1744 case ds_reg: case fs_reg: case gs_reg:
1745 s = names_seg[code - es_reg];
1746 break;
1747 case al_reg: case ah_reg: case cl_reg: case ch_reg:
1748 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1749 s = names8[code - al_reg];
1750 break;
1751 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1752 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1753 if (dflag)
1754 s = names32[code - eAX_reg];
1755 else
1756 s = names16[code - eAX_reg];
1757 break;
1758 default:
1759 s = "<internal disassembler error>";
1760 break;
1762 oappend (s);
1763 return (0);
1767 OP_I (bytemode)
1768 int bytemode;
1770 int op;
1772 switch (bytemode)
1774 case b_mode:
1775 FETCH_DATA (the_info, codep + 1);
1776 op = *codep++ & 0xff;
1777 break;
1778 case v_mode:
1779 if (dflag)
1780 op = get32 ();
1781 else
1782 op = get16 ();
1783 break;
1784 case w_mode:
1785 op = get16 ();
1786 break;
1787 default:
1788 oappend ("<internal disassembler error>");
1789 return (0);
1791 sprintf (scratchbuf, "$0x%x", op);
1792 oappend (scratchbuf);
1793 return (0);
1797 OP_sI (bytemode)
1798 int bytemode;
1800 int op;
1802 switch (bytemode)
1804 case b_mode:
1805 FETCH_DATA (the_info, codep + 1);
1806 op = *(char *)codep++;
1807 break;
1808 case v_mode:
1809 if (dflag)
1810 op = get32 ();
1811 else
1812 op = (short)get16();
1813 break;
1814 case w_mode:
1815 op = (short)get16 ();
1816 break;
1817 default:
1818 oappend ("<internal disassembler error>");
1819 return (0);
1821 sprintf (scratchbuf, "$0x%x", op);
1822 oappend (scratchbuf);
1823 return (0);
1827 OP_J (bytemode)
1828 int bytemode;
1830 int disp;
1831 int mask = -1;
1833 switch (bytemode)
1835 case b_mode:
1836 FETCH_DATA (the_info, codep + 1);
1837 disp = *(char *)codep++;
1838 break;
1839 case v_mode:
1840 if (dflag)
1841 disp = get32 ();
1842 else
1844 disp = (short)get16 ();
1845 /* for some reason, a data16 prefix on a jump instruction
1846 means that the pc is masked to 16 bits after the
1847 displacement is added! */
1848 mask = 0xffff;
1850 break;
1851 default:
1852 oappend ("<internal disassembler error>");
1853 return (0);
1855 disp = (start_pc + codep - start_codep + disp) & mask;
1856 set_op (disp);
1857 sprintf (scratchbuf, "0x%x", disp);
1858 oappend (scratchbuf);
1859 return (0);
1862 /* ARGSUSED */
1864 OP_SEG (dummy)
1865 int dummy;
1867 static char *sreg[] = {
1868 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1871 oappend (sreg[reg]);
1872 return (0);
1876 OP_DIR (size)
1877 int size;
1879 int seg, offset;
1881 switch (size)
1883 case lptr:
1884 if (aflag)
1886 offset = get32 ();
1887 seg = get16 ();
1889 else
1891 offset = get16 ();
1892 seg = get16 ();
1894 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1895 oappend (scratchbuf);
1896 break;
1897 case v_mode:
1898 if (aflag)
1899 offset = get32 ();
1900 else
1901 offset = (short)get16 ();
1903 offset = start_pc + codep - start_codep + offset;
1904 set_op (offset);
1905 sprintf (scratchbuf, "0x%x", offset);
1906 oappend (scratchbuf);
1907 break;
1908 default:
1909 oappend ("<internal disassembler error>");
1910 break;
1912 return (0);
1915 /* ARGSUSED */
1917 OP_OFF (bytemode)
1918 int bytemode;
1920 int off;
1922 if (aflag)
1923 off = get32 ();
1924 else
1925 off = get16 ();
1927 sprintf (scratchbuf, "0x%x", off);
1928 oappend (scratchbuf);
1929 return (0);
1932 /* ARGSUSED */
1934 OP_ESDI (dummy)
1935 int dummy;
1937 oappend ("%es:(");
1938 oappend (aflag ? "%edi" : "%di");
1939 oappend (")");
1940 return (0);
1943 /* ARGSUSED */
1945 OP_DSSI (dummy)
1946 int dummy;
1948 oappend ("%ds:(");
1949 oappend (aflag ? "%esi" : "%si");
1950 oappend (")");
1951 return (0);
1954 /* ARGSUSED */
1956 OP_ONE (dummy)
1957 int dummy;
1959 oappend ("1");
1960 return (0);
1963 /* ARGSUSED */
1965 OP_C (dummy)
1966 int dummy;
1968 codep++; /* skip mod/rm */
1969 sprintf (scratchbuf, "%%cr%d", reg);
1970 oappend (scratchbuf);
1971 return (0);
1974 /* ARGSUSED */
1976 OP_D (dummy)
1977 int dummy;
1979 codep++; /* skip mod/rm */
1980 sprintf (scratchbuf, "%%db%d", reg);
1981 oappend (scratchbuf);
1982 return (0);
1985 /* ARGSUSED */
1987 OP_T (dummy)
1988 int dummy;
1990 codep++; /* skip mod/rm */
1991 sprintf (scratchbuf, "%%tr%d", reg);
1992 oappend (scratchbuf);
1993 return (0);
1997 OP_rm (bytemode)
1998 int bytemode;
2000 switch (bytemode)
2002 case d_mode:
2003 oappend (names32[rm]);
2004 break;
2005 case w_mode:
2006 oappend (names16[rm]);
2007 break;
2009 return (0);