Release 0.5
[wine/multimedia.git] / debugger / i386-pinsn.c
blob9a633611ef9dd7f319eb4d4874828e6173009bee
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 1989, 1991 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
26 * The main tables describing the instructions is essentially a copy
27 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
28 * Programmers Manual. Usually, there is a capital letter, followed
29 * by a small letter. The capital letter tell the addressing mode,
30 * and the small letter tells about the operand size. Refer to
31 * the Intel manual for details.
34 #include "defs.h"
36 #include <ctype.h>
38 /* For the GDB interface at the bottom of the file... */
39 #include "gdbcore.h"
41 #define Eb OP_E, b_mode
42 #define indirEb OP_indirE, b_mode
43 #define Gb OP_G, b_mode
44 #define Ev OP_E, v_mode
45 #define indirEv OP_indirE, v_mode
46 #define Ew OP_E, w_mode
47 #define Ma OP_E, v_mode
48 #define M OP_E, 0
49 #define Mp OP_E, 0 /* ? */
50 #define Gv OP_G, v_mode
51 #define Gw OP_G, w_mode
52 #define Rw OP_rm, w_mode
53 #define Rd OP_rm, d_mode
54 #define Ib OP_I, b_mode
55 #define sIb OP_sI, b_mode /* sign extened byte */
56 #define Iv OP_I, v_mode
57 #define Iw OP_I, w_mode
58 #define Jb OP_J, b_mode
59 #define Jv OP_J, v_mode
60 #define ONE OP_ONE, 0
61 #define Cd OP_C, d_mode
62 #define Dd OP_D, d_mode
63 #define Td OP_T, d_mode
65 #define eAX OP_REG, eAX_reg
66 #define eBX OP_REG, eBX_reg
67 #define eCX OP_REG, eCX_reg
68 #define eDX OP_REG, eDX_reg
69 #define eSP OP_REG, eSP_reg
70 #define eBP OP_REG, eBP_reg
71 #define eSI OP_REG, eSI_reg
72 #define eDI OP_REG, eDI_reg
73 #define AL OP_REG, al_reg
74 #define CL OP_REG, cl_reg
75 #define DL OP_REG, dl_reg
76 #define BL OP_REG, bl_reg
77 #define AH OP_REG, ah_reg
78 #define CH OP_REG, ch_reg
79 #define DH OP_REG, dh_reg
80 #define BH OP_REG, bh_reg
81 #define AX OP_REG, ax_reg
82 #define DX OP_REG, dx_reg
83 #define indirDX OP_REG, indir_dx_reg
85 #define Sw OP_SEG, w_mode
86 #define Ap OP_DIR, lptr
87 #define Av OP_DIR, v_mode
88 #define Ob OP_OFF, b_mode
89 #define Ov OP_OFF, v_mode
90 #define Xb OP_DSSI, b_mode
91 #define Xv OP_DSSI, v_mode
92 #define Yb OP_ESDI, b_mode
93 #define Yv OP_ESDI, v_mode
95 #define es OP_REG, es_reg
96 #define ss OP_REG, ss_reg
97 #define cs OP_REG, cs_reg
98 #define ds OP_REG, ds_reg
99 #define fs OP_REG, fs_reg
100 #define gs OP_REG, gs_reg
102 int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
103 int OP_J(), OP_SEG();
104 int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
105 int OP_D(), OP_T(), OP_rm();
107 static void dofloat (), putop (), append_prefix (), set_op ();
108 static int get16 (), get32 ();
110 #define b_mode 1
111 #define v_mode 2
112 #define w_mode 3
113 #define d_mode 4
115 #define es_reg 100
116 #define cs_reg 101
117 #define ss_reg 102
118 #define ds_reg 103
119 #define fs_reg 104
120 #define gs_reg 105
121 #define eAX_reg 107
122 #define eCX_reg 108
123 #define eDX_reg 109
124 #define eBX_reg 110
125 #define eSP_reg 111
126 #define eBP_reg 112
127 #define eSI_reg 113
128 #define eDI_reg 114
130 #define lptr 115
132 #define al_reg 116
133 #define cl_reg 117
134 #define dl_reg 118
135 #define bl_reg 119
136 #define ah_reg 120
137 #define ch_reg 121
138 #define dh_reg 122
139 #define bh_reg 123
141 #define ax_reg 124
142 #define cx_reg 125
143 #define dx_reg 126
144 #define bx_reg 127
145 #define sp_reg 128
146 #define bp_reg 129
147 #define si_reg 130
148 #define di_reg 131
150 #define indir_dx_reg 150
152 #define GRP1b NULL, NULL, 0
153 #define GRP1S NULL, NULL, 1
154 #define GRP1Ss NULL, NULL, 2
155 #define GRP2b NULL, NULL, 3
156 #define GRP2S NULL, NULL, 4
157 #define GRP2b_one NULL, NULL, 5
158 #define GRP2S_one NULL, NULL, 6
159 #define GRP2b_cl NULL, NULL, 7
160 #define GRP2S_cl NULL, NULL, 8
161 #define GRP3b NULL, NULL, 9
162 #define GRP3S NULL, NULL, 10
163 #define GRP4 NULL, NULL, 11
164 #define GRP5 NULL, NULL, 12
165 #define GRP6 NULL, NULL, 13
166 #define GRP7 NULL, NULL, 14
167 #define GRP8 NULL, NULL, 15
169 #define FLOATCODE 50
170 #define FLOAT NULL, NULL, FLOATCODE
172 struct dis386 {
173 char *name;
174 int (*op1)();
175 int bytemode1;
176 int (*op2)();
177 int bytemode2;
178 int (*op3)();
179 int bytemode3;
182 struct dis386 dis386[] = {
183 /* 00 */
184 { "addb", Eb, Gb },
185 { "addS", Ev, Gv },
186 { "addb", Gb, Eb },
187 { "addS", Gv, Ev },
188 { "addb", AL, Ib },
189 { "addS", eAX, Iv },
190 { "pushl", es },
191 { "popl", es },
192 /* 08 */
193 { "orb", Eb, Gb },
194 { "orS", Ev, Gv },
195 { "orb", Gb, Eb },
196 { "orS", Gv, Ev },
197 { "orb", AL, Ib },
198 { "orS", eAX, Iv },
199 { "pushl", cs },
200 { "(bad)" }, /* 0x0f extended opcode escape */
201 /* 10 */
202 { "adcb", Eb, Gb },
203 { "adcS", Ev, Gv },
204 { "adcb", Gb, Eb },
205 { "adcS", Gv, Ev },
206 { "adcb", AL, Ib },
207 { "adcS", eAX, Iv },
208 { "pushl", ss },
209 { "popl", ss },
210 /* 18 */
211 { "sbbb", Eb, Gb },
212 { "sbbS", Ev, Gv },
213 { "sbbb", Gb, Eb },
214 { "sbbS", Gv, Ev },
215 { "sbbb", AL, Ib },
216 { "sbbS", eAX, Iv },
217 { "pushl", ds },
218 { "popl", ds },
219 /* 20 */
220 { "andb", Eb, Gb },
221 { "andS", Ev, Gv },
222 { "andb", Gb, Eb },
223 { "andS", Gv, Ev },
224 { "andb", AL, Ib },
225 { "andS", eAX, Iv },
226 { "(bad)" }, /* SEG ES prefix */
227 { "daa" },
228 /* 28 */
229 { "subb", Eb, Gb },
230 { "subS", Ev, Gv },
231 { "subb", Gb, Eb },
232 { "subS", Gv, Ev },
233 { "subb", AL, Ib },
234 { "subS", eAX, Iv },
235 { "(bad)" }, /* SEG CS prefix */
236 { "das" },
237 /* 30 */
238 { "xorb", Eb, Gb },
239 { "xorS", Ev, Gv },
240 { "xorb", Gb, Eb },
241 { "xorS", Gv, Ev },
242 { "xorb", AL, Ib },
243 { "xorS", eAX, Iv },
244 { "(bad)" }, /* SEG SS prefix */
245 { "aaa" },
246 /* 38 */
247 { "cmpb", Eb, Gb },
248 { "cmpS", Ev, Gv },
249 { "cmpb", Gb, Eb },
250 { "cmpS", Gv, Ev },
251 { "cmpb", AL, Ib },
252 { "cmpS", eAX, Iv },
253 { "(bad)" }, /* SEG DS prefix */
254 { "aas" },
255 /* 40 */
256 { "incS", eAX },
257 { "incS", eCX },
258 { "incS", eDX },
259 { "incS", eBX },
260 { "incS", eSP },
261 { "incS", eBP },
262 { "incS", eSI },
263 { "incS", eDI },
264 /* 48 */
265 { "decS", eAX },
266 { "decS", eCX },
267 { "decS", eDX },
268 { "decS", eBX },
269 { "decS", eSP },
270 { "decS", eBP },
271 { "decS", eSI },
272 { "decS", eDI },
273 /* 50 */
274 { "pushS", eAX },
275 { "pushS", eCX },
276 { "pushS", eDX },
277 { "pushS", eBX },
278 { "pushS", eSP },
279 { "pushS", eBP },
280 { "pushS", eSI },
281 { "pushS", eDI },
282 /* 58 */
283 { "popS", eAX },
284 { "popS", eCX },
285 { "popS", eDX },
286 { "popS", eBX },
287 { "popS", eSP },
288 { "popS", eBP },
289 { "popS", eSI },
290 { "popS", eDI },
291 /* 60 */
292 { "pusha" },
293 { "popa" },
294 { "boundS", Gv, Ma },
295 { "arpl", Ew, Gw },
296 { "(bad)" }, /* seg fs */
297 { "(bad)" }, /* seg gs */
298 { "(bad)" }, /* op size prefix */
299 { "(bad)" }, /* adr size prefix */
300 /* 68 */
301 { "pushS", Iv }, /* 386 book wrong */
302 { "imulS", Gv, Ev, Iv },
303 { "pushl", sIb }, /* push of byte really pushes 4 bytes */
304 { "imulS", Gv, Ev, Ib },
305 { "insb", Yb, indirDX },
306 { "insS", Yv, indirDX },
307 { "outsb", indirDX, Xb },
308 { "outsS", indirDX, Xv },
309 /* 70 */
310 { "jo", Jb },
311 { "jno", Jb },
312 { "jb", Jb },
313 { "jae", Jb },
314 { "je", Jb },
315 { "jne", Jb },
316 { "jbe", Jb },
317 { "ja", Jb },
318 /* 78 */
319 { "js", Jb },
320 { "jns", Jb },
321 { "jp", Jb },
322 { "jnp", Jb },
323 { "jl", Jb },
324 { "jnl", Jb },
325 { "jle", Jb },
326 { "jg", Jb },
327 /* 80 */
328 { GRP1b },
329 { GRP1S },
330 { "(bad)" },
331 { GRP1Ss },
332 { "testb", Eb, Gb },
333 { "testS", Ev, Gv },
334 { "xchgb", Eb, Gb },
335 { "xchgS", Ev, Gv },
336 /* 88 */
337 { "movb", Eb, Gb },
338 { "movS", Ev, Gv },
339 { "movb", Gb, Eb },
340 { "movS", Gv, Ev },
341 { "movw", Ew, Sw },
342 { "leaS", Gv, M },
343 { "movw", Sw, Ew },
344 { "popS", Ev },
345 /* 90 */
346 { "nop" },
347 { "xchgS", eCX, eAX },
348 { "xchgS", eDX, eAX },
349 { "xchgS", eBX, eAX },
350 { "xchgS", eSP, eAX },
351 { "xchgS", eBP, eAX },
352 { "xchgS", eSI, eAX },
353 { "xchgS", eDI, eAX },
354 /* 98 */
355 { "cwtl" },
356 { "cltd" },
357 { "lcall", Ap },
358 { "(bad)" }, /* fwait */
359 { "pushf" },
360 { "popf" },
361 { "sahf" },
362 { "lahf" },
363 /* a0 */
364 { "movb", AL, Ob },
365 { "movS", eAX, Ov },
366 { "movb", Ob, AL },
367 { "movS", Ov, eAX },
368 { "movsb", Yb, Xb },
369 { "movsS", Yv, Xv },
370 { "cmpsb", Yb, Xb },
371 { "cmpsS", Yv, Xv },
372 /* a8 */
373 { "testb", AL, Ib },
374 { "testS", eAX, Iv },
375 { "stosb", Yb, AL },
376 { "stosS", Yv, eAX },
377 { "lodsb", AL, Xb },
378 { "lodsS", eAX, Xv },
379 { "scasb", AL, Xb },
380 { "scasS", eAX, Xv },
381 /* b0 */
382 { "movb", AL, Ib },
383 { "movb", CL, Ib },
384 { "movb", DL, Ib },
385 { "movb", BL, Ib },
386 { "movb", AH, Ib },
387 { "movb", CH, Ib },
388 { "movb", DH, Ib },
389 { "movb", BH, Ib },
390 /* b8 */
391 { "movS", eAX, Iv },
392 { "movS", eCX, Iv },
393 { "movS", eDX, Iv },
394 { "movS", eBX, Iv },
395 { "movS", eSP, Iv },
396 { "movS", eBP, Iv },
397 { "movS", eSI, Iv },
398 { "movS", eDI, Iv },
399 /* c0 */
400 { GRP2b },
401 { GRP2S },
402 { "ret", Iw },
403 { "ret" },
404 { "lesS", Gv, Mp },
405 { "ldsS", Gv, Mp },
406 { "movb", Eb, Ib },
407 { "movS", Ev, Iv },
408 /* c8 */
409 { "enter", Iw, Ib },
410 { "leave" },
411 { "lret", Iw },
412 { "lret" },
413 { "int3" },
414 { "int", Ib },
415 { "into" },
416 { "iret" },
417 /* d0 */
418 { GRP2b_one },
419 { GRP2S_one },
420 { GRP2b_cl },
421 { GRP2S_cl },
422 { "aam", Ib },
423 { "aad", Ib },
424 { "(bad)" },
425 { "xlat" },
426 /* d8 */
427 { FLOAT },
428 { FLOAT },
429 { FLOAT },
430 { FLOAT },
431 { FLOAT },
432 { FLOAT },
433 { FLOAT },
434 { FLOAT },
435 /* e0 */
436 { "loopne", Jb },
437 { "loope", Jb },
438 { "loop", Jb },
439 { "jCcxz", Jb },
440 { "inb", AL, Ib },
441 { "inS", eAX, Ib },
442 { "outb", Ib, AL },
443 { "outS", Ib, eAX },
444 /* e8 */
445 { "call", Av },
446 { "jmp", Jv },
447 { "ljmp", Ap },
448 { "jmp", Jb },
449 { "inb", AL, indirDX },
450 { "inS", eAX, indirDX },
451 { "outb", indirDX, AL },
452 { "outS", indirDX, eAX },
453 /* f0 */
454 { "(bad)" }, /* lock prefix */
455 { "(bad)" },
456 { "(bad)" }, /* repne */
457 { "(bad)" }, /* repz */
458 { "hlt" },
459 { "cmc" },
460 { GRP3b },
461 { GRP3S },
462 /* f8 */
463 { "clc" },
464 { "stc" },
465 { "cli" },
466 { "sti" },
467 { "cld" },
468 { "std" },
469 { GRP4 },
470 { GRP5 },
473 struct dis386 dis386_twobyte[] = {
474 /* 00 */
475 { GRP6 },
476 { GRP7 },
477 { "larS", Gv, Ew },
478 { "lslS", Gv, Ew },
479 { "(bad)" },
480 { "(bad)" },
481 { "clts" },
482 { "(bad)" },
483 /* 08 */
484 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
485 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
486 /* 10 */
487 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
488 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
489 /* 18 */
490 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
491 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
492 /* 20 */
493 /* these are all backward in appendix A of the intel book */
494 { "movl", Rd, Cd },
495 { "movl", Rd, Dd },
496 { "movl", Cd, Rd },
497 { "movl", Dd, Rd },
498 { "movl", Rd, Td },
499 { "(bad)" },
500 { "movl", Td, Rd },
501 { "(bad)" },
502 /* 28 */
503 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
504 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
505 /* 30 */
506 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
507 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
508 /* 38 */
509 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
510 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
511 /* 40 */
512 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
513 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
514 /* 48 */
515 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
516 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
517 /* 50 */
518 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
519 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
520 /* 58 */
521 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
522 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
523 /* 60 */
524 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
525 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
526 /* 68 */
527 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
528 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
529 /* 70 */
530 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
531 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
532 /* 78 */
533 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
534 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
535 /* 80 */
536 { "jo", Jv },
537 { "jno", Jv },
538 { "jb", Jv },
539 { "jae", Jv },
540 { "je", Jv },
541 { "jne", Jv },
542 { "jbe", Jv },
543 { "ja", Jv },
544 /* 88 */
545 { "js", Jv },
546 { "jns", Jv },
547 { "jp", Jv },
548 { "jnp", Jv },
549 { "jl", Jv },
550 { "jge", Jv },
551 { "jle", Jv },
552 { "jg", Jv },
553 /* 90 */
554 { "seto", Eb },
555 { "setno", Eb },
556 { "setb", Eb },
557 { "setae", Eb },
558 { "sete", Eb },
559 { "setne", Eb },
560 { "setbe", Eb },
561 { "seta", Eb },
562 /* 98 */
563 { "sets", Eb },
564 { "setns", Eb },
565 { "setp", Eb },
566 { "setnp", Eb },
567 { "setl", Eb },
568 { "setge", Eb },
569 { "setle", Eb },
570 { "setg", Eb },
571 /* a0 */
572 { "pushl", fs },
573 { "popl", fs },
574 { "(bad)" },
575 { "btS", Ev, Gv },
576 { "shldS", Ev, Gv, Ib },
577 { "shldS", Ev, Gv, CL },
578 { "(bad)" },
579 { "(bad)" },
580 /* a8 */
581 { "pushl", gs },
582 { "popl", gs },
583 { "(bad)" },
584 { "btsS", Ev, Gv },
585 { "shrdS", Ev, Gv, Ib },
586 { "shrdS", Ev, Gv, CL },
587 { "(bad)" },
588 { "imulS", Gv, Ev },
589 /* b0 */
590 { "(bad)" },
591 { "(bad)" },
592 { "lssS", Gv, Mp }, /* 386 lists only Mp */
593 { "btrS", Ev, Gv },
594 { "lfsS", Gv, Mp }, /* 386 lists only Mp */
595 { "lgsS", Gv, Mp }, /* 386 lists only Mp */
596 { "movzbS", Gv, Eb },
597 { "movzwS", Gv, Ew },
598 /* b8 */
599 { "(bad)" },
600 { "(bad)" },
601 { GRP8 },
602 { "btcS", Ev, Gv },
603 { "bsfS", Gv, Ev },
604 { "bsrS", Gv, Ev },
605 { "movsbS", Gv, Eb },
606 { "movswS", Gv, Ew },
607 /* c0 */
608 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
609 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
610 /* c8 */
611 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
612 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
613 /* d0 */
614 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
615 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
616 /* d8 */
617 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
618 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
619 /* e0 */
620 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
621 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
622 /* e8 */
623 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
624 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
625 /* f0 */
626 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
627 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
628 /* f8 */
629 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
630 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
633 static char obuf[100];
634 static char *obufp;
635 static char scratchbuf[100];
636 static unsigned char *start_codep;
637 static unsigned char *codep;
638 static int mod;
639 static int rm;
640 static int reg;
641 static void oappend ();
643 static char *names32[]={
644 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
646 static char *names16[] = {
647 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
649 static char *names8[] = {
650 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
652 static char *names_seg[] = {
653 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
656 struct dis386 grps[][8] = {
657 /* GRP1b */
659 { "addb", Eb, Ib },
660 { "orb", Eb, Ib },
661 { "adcb", Eb, Ib },
662 { "sbbb", Eb, Ib },
663 { "andb", Eb, Ib },
664 { "subb", Eb, Ib },
665 { "xorb", Eb, Ib },
666 { "cmpb", Eb, Ib }
668 /* GRP1S */
670 { "addS", Ev, Iv },
671 { "orS", Ev, Iv },
672 { "adcS", Ev, Iv },
673 { "sbbS", Ev, Iv },
674 { "andS", Ev, Iv },
675 { "subS", Ev, Iv },
676 { "xorS", Ev, Iv },
677 { "cmpS", Ev, Iv }
679 /* GRP1Ss */
681 { "addS", Ev, sIb },
682 { "orS", Ev, sIb },
683 { "adcS", Ev, sIb },
684 { "sbbS", Ev, sIb },
685 { "andS", Ev, sIb },
686 { "subS", Ev, sIb },
687 { "xorS", Ev, sIb },
688 { "cmpS", Ev, sIb }
690 /* GRP2b */
692 { "rolb", Eb, Ib },
693 { "rorb", Eb, Ib },
694 { "rclb", Eb, Ib },
695 { "rcrb", Eb, Ib },
696 { "shlb", Eb, Ib },
697 { "shrb", Eb, Ib },
698 { "(bad)" },
699 { "sarb", Eb, Ib },
701 /* GRP2S */
703 { "rolS", Ev, Ib },
704 { "rorS", Ev, Ib },
705 { "rclS", Ev, Ib },
706 { "rcrS", Ev, Ib },
707 { "shlS", Ev, Ib },
708 { "shrS", Ev, Ib },
709 { "(bad)" },
710 { "sarS", Ev, Ib },
712 /* GRP2b_one */
714 { "rolb", Eb },
715 { "rorb", Eb },
716 { "rclb", Eb },
717 { "rcrb", Eb },
718 { "shlb", Eb },
719 { "shrb", Eb },
720 { "(bad)" },
721 { "sarb", Eb },
723 /* GRP2S_one */
725 { "rolS", Ev },
726 { "rorS", Ev },
727 { "rclS", Ev },
728 { "rcrS", Ev },
729 { "shlS", Ev },
730 { "shrS", Ev },
731 { "(bad)" },
732 { "sarS", Ev },
734 /* GRP2b_cl */
736 { "rolb", Eb, CL },
737 { "rorb", Eb, CL },
738 { "rclb", Eb, CL },
739 { "rcrb", Eb, CL },
740 { "shlb", Eb, CL },
741 { "shrb", Eb, CL },
742 { "(bad)" },
743 { "sarb", Eb, CL },
745 /* GRP2S_cl */
747 { "rolS", Ev, CL },
748 { "rorS", Ev, CL },
749 { "rclS", Ev, CL },
750 { "rcrS", Ev, CL },
751 { "shlS", Ev, CL },
752 { "shrS", Ev, CL },
753 { "(bad)" },
754 { "sarS", Ev, CL }
756 /* GRP3b */
758 { "testb", Eb, Ib },
759 { "(bad)", Eb },
760 { "notb", Eb },
761 { "negb", Eb },
762 { "mulb", AL, Eb },
763 { "imulb", AL, Eb },
764 { "divb", AL, Eb },
765 { "idivb", AL, Eb }
767 /* GRP3S */
769 { "testS", Ev, Iv },
770 { "(bad)" },
771 { "notS", Ev },
772 { "negS", Ev },
773 { "mulS", eAX, Ev },
774 { "imulS", eAX, Ev },
775 { "divS", eAX, Ev },
776 { "idivS", eAX, Ev },
778 /* GRP4 */
780 { "incb", Eb },
781 { "decb", Eb },
782 { "(bad)" },
783 { "(bad)" },
784 { "(bad)" },
785 { "(bad)" },
786 { "(bad)" },
787 { "(bad)" },
789 /* GRP5 */
791 { "incS", Ev },
792 { "decS", Ev },
793 { "call", indirEv },
794 { "lcall", indirEv },
795 { "jmp", indirEv },
796 { "ljmp", indirEv },
797 { "pushS", Ev },
798 { "(bad)" },
800 /* GRP6 */
802 { "sldt", Ew },
803 { "str", Ew },
804 { "lldt", Ew },
805 { "ltr", Ew },
806 { "verr", Ew },
807 { "verw", Ew },
808 { "(bad)" },
809 { "(bad)" }
811 /* GRP7 */
813 { "sgdt", Ew },
814 { "sidt", Ew },
815 { "lgdt", Ew },
816 { "lidt", Ew },
817 { "smsw", Ew },
818 { "(bad)" },
819 { "lmsw", Ew },
820 { "(bad)" },
822 /* GRP8 */
824 { "(bad)" },
825 { "(bad)" },
826 { "(bad)" },
827 { "(bad)" },
828 { "btS", Ev, Ib },
829 { "btsS", Ev, Ib },
830 { "btrS", Ev, Ib },
831 { "btcS", Ev, Ib },
835 #define PREFIX_REPZ 1
836 #define PREFIX_REPNZ 2
837 #define PREFIX_LOCK 4
838 #define PREFIX_CS 8
839 #define PREFIX_SS 0x10
840 #define PREFIX_DS 0x20
841 #define PREFIX_ES 0x40
842 #define PREFIX_FS 0x80
843 #define PREFIX_GS 0x100
844 #define PREFIX_DATA 0x200
845 #define PREFIX_ADR 0x400
846 #define PREFIX_FWAIT 0x800
848 static int prefixes;
850 static void
851 ckprefix ()
853 prefixes = 0;
854 while (1)
856 switch (*codep)
858 case 0xf3:
859 prefixes |= PREFIX_REPZ;
860 break;
861 case 0xf2:
862 prefixes |= PREFIX_REPNZ;
863 break;
864 case 0xf0:
865 prefixes |= PREFIX_LOCK;
866 break;
867 case 0x2e:
868 prefixes |= PREFIX_CS;
869 break;
870 case 0x36:
871 prefixes |= PREFIX_SS;
872 break;
873 case 0x3e:
874 prefixes |= PREFIX_DS;
875 break;
876 case 0x26:
877 prefixes |= PREFIX_ES;
878 break;
879 case 0x64:
880 prefixes |= PREFIX_FS;
881 break;
882 case 0x65:
883 prefixes |= PREFIX_GS;
884 break;
885 case 0x66:
886 prefixes |= PREFIX_DATA;
887 break;
888 case 0x67:
889 prefixes |= PREFIX_ADR;
890 break;
891 case 0x9b:
892 prefixes |= PREFIX_FWAIT;
893 break;
894 default:
895 return;
897 codep++;
901 static int dflag;
902 static int aflag;
904 static char op1out[100], op2out[100], op3out[100];
905 static int op_address[3], op_ad, op_index[3];
906 static int start_pc;
907 extern void fputs_filtered ();
910 * disassemble the first instruction in 'inbuf'. You have to make
911 * sure all of the bytes of the instruction are filled in.
912 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
913 * (see topic "Redundant prefixes" in the "Differences from 8086"
914 * section of the "Virtual 8086 Mode" chapter.)
915 * 'pc' should be the address of this instruction, it will
916 * be used to print the target address if this is a relative jump or call
917 * 'outbuf' gets filled in with the disassembled instruction. it should
918 * be long enough to hold the longest disassembled instruction.
919 * 100 bytes is certainly enough, unless symbol printing is added later
920 * The function returns the length of this instruction in bytes.
924 i386dis (pc, inbuf, stream)
925 int pc;
926 unsigned char *inbuf;
927 FILE *stream;
929 struct dis386 *dp;
930 int i;
931 int enter_instruction;
932 char *first, *second, *third;
933 int needcomma;
935 obuf[0] = 0;
936 op1out[0] = 0;
937 op2out[0] = 0;
938 op3out[0] = 0;
940 op_index[0] = op_index[1] = op_index[2] = -1;
942 start_pc = pc;
943 start_codep = inbuf;
944 codep = inbuf;
946 ckprefix ();
948 if (*codep == 0xc8)
949 enter_instruction = 1;
950 else
951 enter_instruction = 0;
953 obufp = obuf;
955 if (prefixes & PREFIX_REPZ)
956 oappend ("repz ");
957 if (prefixes & PREFIX_REPNZ)
958 oappend ("repnz ");
959 if (prefixes & PREFIX_LOCK)
960 oappend ("lock ");
962 if ((prefixes & PREFIX_FWAIT)
963 && ((*codep < 0xd8) || (*codep > 0xdf)))
965 /* fwait not followed by floating point instruction */
966 fputs_filtered ("fwait", stream);
967 return (1);
970 /* these would be initialized to 0 if disassembling for 8086 or 286 */
972 if (prefixes & PREFIX_DATA)
973 dflag ^= 1;
975 if (prefixes & PREFIX_ADR)
977 aflag ^= 1;
978 oappend ("addr16 ");
981 if (*codep == 0x0f)
982 dp = &dis386_twobyte[*++codep];
983 else
984 dp = &dis386[*codep];
985 codep++;
986 mod = (*codep >> 6) & 3;
987 reg = (*codep >> 3) & 7;
988 rm = *codep & 7;
990 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
992 dofloat ();
994 else
996 if (dp->name == NULL)
997 dp = &grps[dp->bytemode1][reg];
999 putop (dp->name);
1001 obufp = op1out;
1002 op_ad = 2;
1003 if (dp->op1)
1004 (*dp->op1)(dp->bytemode1);
1006 obufp = op2out;
1007 op_ad = 1;
1008 if (dp->op2)
1009 (*dp->op2)(dp->bytemode2);
1011 obufp = op3out;
1012 op_ad = 0;
1013 if (dp->op3)
1014 (*dp->op3)(dp->bytemode3);
1017 obufp = obuf + strlen (obuf);
1018 for (i = strlen (obuf); i < 6; i++)
1019 oappend (" ");
1020 oappend (" ");
1021 fputs_filtered (obuf, stream);
1023 /* enter instruction is printed with operands in the
1024 * same order as the intel book; everything else
1025 * is printed in reverse order
1027 if (enter_instruction)
1029 first = op1out;
1030 second = op2out;
1031 third = op3out;
1032 op_ad = op_index[0];
1033 op_index[0] = op_index[2];
1034 op_index[2] = op_ad;
1036 else
1038 first = op3out;
1039 second = op2out;
1040 third = op1out;
1042 needcomma = 0;
1043 if (*first)
1045 if (op_index[0] != -1)
1046 print_address (op_address[op_index[0]], stream);
1047 else
1048 fputs_filtered (first, stream);
1049 needcomma = 1;
1051 if (*second)
1053 if (needcomma)
1054 fputs_filtered (",", stream);
1055 if (op_index[1] != -1)
1056 print_address (op_address[op_index[1]], stream);
1057 else
1058 fputs_filtered (second, stream);
1059 needcomma = 1;
1061 if (*third)
1063 if (needcomma)
1064 fputs_filtered (",", stream);
1065 if (op_index[2] != -1)
1066 print_address (op_address[op_index[2]], stream);
1067 else
1068 fputs_filtered (third, stream);
1070 return (codep - inbuf);
1073 char *float_mem[] = {
1074 /* d8 */
1075 "fadds",
1076 "fmuls",
1077 "fcoms",
1078 "fcomps",
1079 "fsubs",
1080 "fsubrs",
1081 "fdivs",
1082 "fdivrs",
1083 /* d9 */
1084 "flds",
1085 "(bad)",
1086 "fsts",
1087 "fstps",
1088 "fldenv",
1089 "fldcw",
1090 "fNstenv",
1091 "fNstcw",
1092 /* da */
1093 "fiaddl",
1094 "fimull",
1095 "ficoml",
1096 "ficompl",
1097 "fisubl",
1098 "fisubrl",
1099 "fidivl",
1100 "fidivrl",
1101 /* db */
1102 "fildl",
1103 "(bad)",
1104 "fistl",
1105 "fistpl",
1106 "(bad)",
1107 "fldt",
1108 "(bad)",
1109 "fstpt",
1110 /* dc */
1111 "faddl",
1112 "fmull",
1113 "fcoml",
1114 "fcompl",
1115 "fsubl",
1116 "fsubrl",
1117 "fdivl",
1118 "fdivrl",
1119 /* dd */
1120 "fldl",
1121 "(bad)",
1122 "fstl",
1123 "fstpl",
1124 "frstor",
1125 "(bad)",
1126 "fNsave",
1127 "fNstsw",
1128 /* de */
1129 "fiadd",
1130 "fimul",
1131 "ficom",
1132 "ficomp",
1133 "fisub",
1134 "fisubr",
1135 "fidiv",
1136 "fidivr",
1137 /* df */
1138 "fild",
1139 "(bad)",
1140 "fist",
1141 "fistp",
1142 "fbld",
1143 "fildll",
1144 "fbstp",
1145 "fistpll",
1148 #define ST OP_ST, 0
1149 #define STi OP_STi, 0
1150 int OP_ST(), OP_STi();
1152 #define FGRPd9_2 NULL, NULL, 0
1153 #define FGRPd9_4 NULL, NULL, 1
1154 #define FGRPd9_5 NULL, NULL, 2
1155 #define FGRPd9_6 NULL, NULL, 3
1156 #define FGRPd9_7 NULL, NULL, 4
1157 #define FGRPda_5 NULL, NULL, 5
1158 #define FGRPdb_4 NULL, NULL, 6
1159 #define FGRPde_3 NULL, NULL, 7
1160 #define FGRPdf_4 NULL, NULL, 8
1162 struct dis386 float_reg[][8] = {
1163 /* d8 */
1165 { "fadd", ST, STi },
1166 { "fmul", ST, STi },
1167 { "fcom", STi },
1168 { "fcomp", STi },
1169 { "fsub", ST, STi },
1170 { "fsubr", ST, STi },
1171 { "fdiv", ST, STi },
1172 { "fdivr", ST, STi },
1174 /* d9 */
1176 { "fld", STi },
1177 { "fxch", STi },
1178 { FGRPd9_2 },
1179 { "(bad)" },
1180 { FGRPd9_4 },
1181 { FGRPd9_5 },
1182 { FGRPd9_6 },
1183 { FGRPd9_7 },
1185 /* da */
1187 { "(bad)" },
1188 { "(bad)" },
1189 { "(bad)" },
1190 { "(bad)" },
1191 { "(bad)" },
1192 { FGRPda_5 },
1193 { "(bad)" },
1194 { "(bad)" },
1196 /* db */
1198 { "(bad)" },
1199 { "(bad)" },
1200 { "(bad)" },
1201 { "(bad)" },
1202 { FGRPdb_4 },
1203 { "(bad)" },
1204 { "(bad)" },
1205 { "(bad)" },
1207 /* dc */
1209 { "fadd", STi, ST },
1210 { "fmul", STi, ST },
1211 { "(bad)" },
1212 { "(bad)" },
1213 { "fsub", STi, ST },
1214 { "fsubr", STi, ST },
1215 { "fdiv", STi, ST },
1216 { "fdivr", STi, ST },
1218 /* dd */
1220 { "ffree", STi },
1221 { "(bad)" },
1222 { "fst", STi },
1223 { "fstp", STi },
1224 { "fucom", STi },
1225 { "fucomp", STi },
1226 { "(bad)" },
1227 { "(bad)" },
1229 /* de */
1231 { "faddp", STi, ST },
1232 { "fmulp", STi, ST },
1233 { "(bad)" },
1234 { FGRPde_3 },
1235 { "fsubp", STi, ST },
1236 { "fsubrp", STi, ST },
1237 { "fdivp", STi, ST },
1238 { "fdivrp", STi, ST },
1240 /* df */
1242 { "(bad)" },
1243 { "(bad)" },
1244 { "(bad)" },
1245 { "(bad)" },
1246 { FGRPdf_4 },
1247 { "(bad)" },
1248 { "(bad)" },
1249 { "(bad)" },
1254 char *fgrps[][8] = {
1255 /* d9_2 0 */
1257 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1260 /* d9_4 1 */
1262 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1265 /* d9_5 2 */
1267 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1270 /* d9_6 3 */
1272 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1275 /* d9_7 4 */
1277 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1280 /* da_5 5 */
1282 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1285 /* db_4 6 */
1287 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1288 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1291 /* de_3 7 */
1293 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1296 /* df_4 8 */
1298 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1302 static void
1303 dofloat ()
1305 struct dis386 *dp;
1306 unsigned char floatop;
1308 floatop = codep[-1];
1310 if (mod != 3)
1312 putop (float_mem[(floatop - 0xd8) * 8 + reg]);
1313 obufp = op1out;
1314 OP_E (v_mode);
1315 return;
1317 codep++;
1319 dp = &float_reg[floatop - 0xd8][reg];
1320 if (dp->name == NULL)
1322 putop (fgrps[dp->bytemode1][rm]);
1323 /* instruction fnstsw is only one with strange arg */
1324 if (floatop == 0xdf && *codep == 0xe0)
1325 strcpy (op1out, "%eax");
1327 else
1329 putop (dp->name);
1330 obufp = op1out;
1331 if (dp->op1)
1332 (*dp->op1)(dp->bytemode1);
1333 obufp = op2out;
1334 if (dp->op2)
1335 (*dp->op2)(dp->bytemode2);
1339 /* ARGSUSED */
1341 OP_ST (ignore)
1342 int ignore;
1344 oappend ("%st");
1345 return (0);
1348 /* ARGSUSED */
1350 OP_STi (ignore)
1351 int ignore;
1353 sprintf (scratchbuf, "%%st(%d)", rm);
1354 oappend (scratchbuf);
1355 return (0);
1359 /* capital letters in template are macros */
1360 static void
1361 putop (template)
1362 char *template;
1364 char *p;
1366 for (p = template; *p; p++)
1368 switch (*p)
1370 default:
1371 *obufp++ = *p;
1372 break;
1373 case 'C': /* For jcxz/jecxz */
1374 if (aflag == 0)
1375 *obufp++ = 'e';
1376 break;
1377 case 'N':
1378 if ((prefixes & PREFIX_FWAIT) == 0)
1379 *obufp++ = 'n';
1380 break;
1381 case 'S':
1382 /* operand size flag */
1383 if (dflag)
1384 *obufp++ = 'l';
1385 else
1386 *obufp++ = 'w';
1387 break;
1390 *obufp = 0;
1393 static void
1394 oappend (s)
1395 char *s;
1397 strcpy (obufp, s);
1398 obufp += strlen (s);
1399 *obufp = 0;
1402 static void
1403 append_prefix ()
1405 if (prefixes & PREFIX_CS)
1406 oappend ("%cs:");
1407 if (prefixes & PREFIX_DS)
1408 oappend ("%ds:");
1409 if (prefixes & PREFIX_SS)
1410 oappend ("%ss:");
1411 if (prefixes & PREFIX_ES)
1412 oappend ("%es:");
1413 if (prefixes & PREFIX_FS)
1414 oappend ("%fs:");
1415 if (prefixes & PREFIX_GS)
1416 oappend ("%gs:");
1420 OP_indirE (bytemode)
1421 int bytemode;
1423 oappend ("*");
1424 OP_E (bytemode);
1425 return (0);
1429 OP_E (bytemode)
1430 int bytemode;
1432 int disp;
1433 int havesib;
1434 int base;
1435 int index;
1436 int scale;
1437 int havebase;
1439 /* skip mod/rm byte */
1440 codep++;
1442 havesib = 0;
1443 havebase = 0;
1444 disp = 0;
1446 if (mod == 3)
1448 switch (bytemode)
1450 case b_mode:
1451 oappend (names8[rm]);
1452 break;
1453 case w_mode:
1454 oappend (names16[rm]);
1455 break;
1456 case v_mode:
1457 if (dflag)
1458 oappend (names32[rm]);
1459 else
1460 oappend (names16[rm]);
1461 break;
1462 default:
1463 oappend ("<bad dis table>");
1464 break;
1466 return (0);
1469 append_prefix ();
1471 if (bytemode == w_mode || (bytemode == v_mode && !dflag))
1473 if (mod == 0 && rm == 6)
1475 sprintf(scratchbuf, "%04.4x", get16());
1476 oappend(scratchbuf);
1477 return 0;
1480 disp = 0;
1481 if (mod == 1)
1482 disp = *(char *)codep++;
1483 else if (mod == 2)
1484 disp = get16();
1485 if (disp != 0)
1487 sprintf(scratchbuf, "0x%x", disp);
1488 oappend(scratchbuf);
1491 switch (rm)
1493 case 0:
1494 oappend("(%bx,%si)");
1495 break;
1496 case 1:
1497 oappend("(%bx,%di)");
1498 break;
1499 case 2:
1500 oappend("(%bp,%si)");
1501 break;
1502 case 3:
1503 oappend("(%bp,%di)");
1504 break;
1505 case 4:
1506 oappend("(%si)");
1507 break;
1508 case 5:
1509 oappend("(%di)");
1510 break;
1511 case 6:
1512 oappend("(%bp)");
1513 break;
1514 case 7:
1515 oappend("(%bx)");
1516 break;
1518 return 0;
1521 if (rm == 4)
1523 havesib = 1;
1524 havebase = 1;
1525 scale = (*codep >> 6) & 3;
1526 index = (*codep >> 3) & 7;
1527 base = *codep & 7;
1528 codep++;
1531 switch (mod)
1533 case 0:
1534 switch (rm)
1536 case 4:
1537 /* implies havesib and havebase */
1538 if (base == 5) {
1539 havebase = 0;
1540 disp = get32 ();
1542 break;
1543 case 5:
1544 disp = get32 ();
1545 break;
1546 default:
1547 havebase = 1;
1548 base = rm;
1549 break;
1551 break;
1552 case 1:
1553 disp = *(char *)codep++;
1554 if (rm != 4)
1556 havebase = 1;
1557 base = rm;
1559 break;
1560 case 2:
1561 disp = get32 ();
1562 if (rm != 4)
1564 havebase = 1;
1565 base = rm;
1567 break;
1570 if (mod != 0 || rm == 5 || (havesib && base == 5))
1572 sprintf (scratchbuf, "0x%x", disp);
1573 oappend (scratchbuf);
1576 if (havebase || havesib)
1578 oappend ("(");
1579 if (havebase)
1580 oappend (names32[base]);
1581 if (havesib)
1583 if (index != 4)
1585 sprintf (scratchbuf, ",%s", names32[index]);
1586 oappend (scratchbuf);
1588 sprintf (scratchbuf, ",%d", 1 << scale);
1589 oappend (scratchbuf);
1591 oappend (")");
1593 return (0);
1597 OP_G (bytemode)
1598 int bytemode;
1600 switch (bytemode)
1602 case b_mode:
1603 oappend (names8[reg]);
1604 break;
1605 case w_mode:
1606 oappend (names16[reg]);
1607 break;
1608 case d_mode:
1609 oappend (names32[reg]);
1610 break;
1611 case v_mode:
1612 if (dflag)
1613 oappend (names32[reg]);
1614 else
1615 oappend (names16[reg]);
1616 break;
1617 default:
1618 oappend ("<internal disassembler error>");
1619 break;
1621 return (0);
1624 static int
1625 get32 ()
1627 int x = 0;
1629 x = *codep++ & 0xff;
1630 x |= (*codep++ & 0xff) << 8;
1631 x |= (*codep++ & 0xff) << 16;
1632 x |= (*codep++ & 0xff) << 24;
1633 return (x);
1636 static int
1637 get16 ()
1639 int x = 0;
1641 x = *codep++ & 0xff;
1642 x |= (*codep++ & 0xff) << 8;
1643 return (x);
1646 static void
1647 set_op (op)
1648 int op;
1650 op_index[op_ad] = op_ad;
1651 op_address[op_ad] = op;
1655 OP_REG (code)
1656 int code;
1658 char *s;
1660 switch (code)
1662 case indir_dx_reg: s = "(%dx)"; break;
1663 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1664 case sp_reg: case bp_reg: case si_reg: case di_reg:
1665 s = names16[code - ax_reg];
1666 break;
1667 case es_reg: case ss_reg: case cs_reg:
1668 case ds_reg: case fs_reg: case gs_reg:
1669 s = names_seg[code - es_reg];
1670 break;
1671 case al_reg: case ah_reg: case cl_reg: case ch_reg:
1672 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1673 s = names8[code - al_reg];
1674 break;
1675 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1676 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1677 if (dflag)
1678 s = names32[code - eAX_reg];
1679 else
1680 s = names16[code - eAX_reg];
1681 break;
1682 default:
1683 s = "<internal disassembler error>";
1684 break;
1686 oappend (s);
1687 return (0);
1691 OP_I (bytemode)
1692 int bytemode;
1694 int op;
1696 switch (bytemode)
1698 case b_mode:
1699 op = *codep++ & 0xff;
1700 break;
1701 case v_mode:
1702 if (dflag)
1703 op = get32 ();
1704 else
1705 op = get16 ();
1706 break;
1707 case w_mode:
1708 op = get16 ();
1709 break;
1710 default:
1711 oappend ("<internal disassembler error>");
1712 return (0);
1714 sprintf (scratchbuf, "$0x%x", op);
1715 oappend (scratchbuf);
1716 return (0);
1720 OP_sI (bytemode)
1721 int bytemode;
1723 int op;
1725 switch (bytemode)
1727 case b_mode:
1728 op = *(char *)codep++;
1729 break;
1730 case v_mode:
1731 if (dflag)
1732 op = get32 ();
1733 else
1734 op = (short)get16();
1735 break;
1736 case w_mode:
1737 op = (short)get16 ();
1738 break;
1739 default:
1740 oappend ("<internal disassembler error>");
1741 return (0);
1743 sprintf (scratchbuf, "$0x%x", op);
1744 oappend (scratchbuf);
1745 return (0);
1749 OP_J (bytemode)
1750 int bytemode;
1752 int disp;
1753 int mask = -1;
1755 switch (bytemode)
1757 case b_mode:
1758 disp = *(char *)codep++;
1759 break;
1760 case v_mode:
1761 if (dflag)
1762 disp = get32 ();
1763 else
1765 disp = (short)get16 ();
1766 /* for some reason, a data16 prefix on a jump instruction
1767 means that the pc is masked to 16 bits after the
1768 displacement is added! */
1769 mask = 0xffff;
1771 break;
1772 default:
1773 oappend ("<internal disassembler error>");
1774 return (0);
1776 disp = (start_pc + codep - start_codep + disp) & mask;
1777 set_op (disp);
1778 sprintf (scratchbuf, "0x%x", disp);
1779 oappend (scratchbuf);
1780 return (0);
1783 /* ARGSUSED */
1785 OP_SEG (dummy)
1786 int dummy;
1788 static char *sreg[] = {
1789 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1792 oappend (sreg[reg]);
1793 return (0);
1797 OP_DIR (size)
1798 int size;
1800 int seg, offset;
1802 switch (size)
1804 case lptr:
1805 if (aflag)
1807 offset = get32 ();
1808 seg = get16 ();
1810 else
1812 offset = get16 ();
1813 seg = get16 ();
1815 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1816 oappend (scratchbuf);
1817 break;
1818 case v_mode:
1819 if (aflag)
1820 offset = get32 ();
1821 else
1822 offset = (short)get16 ();
1824 offset = start_pc + codep - start_codep + offset;
1825 set_op (offset);
1826 sprintf (scratchbuf, "0x%x", offset);
1827 oappend (scratchbuf);
1828 break;
1829 default:
1830 oappend ("<internal disassembler error>");
1831 break;
1833 return (0);
1836 /* ARGSUSED */
1838 OP_OFF (bytemode)
1839 int bytemode;
1841 int off;
1843 if (aflag)
1844 off = get32 ();
1845 else
1846 off = get16 ();
1848 sprintf (scratchbuf, "0x%x", off);
1849 oappend (scratchbuf);
1850 return (0);
1853 /* ARGSUSED */
1855 OP_ESDI (dummy)
1856 int dummy;
1858 oappend ("%es:(");
1859 oappend (aflag ? "%edi" : "%di");
1860 oappend (")");
1861 return (0);
1864 /* ARGSUSED */
1866 OP_DSSI (dummy)
1867 int dummy;
1869 oappend ("%ds:(");
1870 oappend (aflag ? "%esi" : "%si");
1871 oappend (")");
1872 return (0);
1875 /* ARGSUSED */
1877 OP_ONE (dummy)
1878 int dummy;
1880 oappend ("1");
1881 return (0);
1884 /* ARGSUSED */
1886 OP_C (dummy)
1887 int dummy;
1889 codep++; /* skip mod/rm */
1890 sprintf (scratchbuf, "%%cr%d", reg);
1891 oappend (scratchbuf);
1892 return (0);
1895 /* ARGSUSED */
1897 OP_D (dummy)
1898 int dummy;
1900 codep++; /* skip mod/rm */
1901 sprintf (scratchbuf, "%%db%d", reg);
1902 oappend (scratchbuf);
1903 return (0);
1906 /* ARGSUSED */
1908 OP_T (dummy)
1909 int dummy;
1911 codep++; /* skip mod/rm */
1912 sprintf (scratchbuf, "%%tr%d", reg);
1913 oappend (scratchbuf);
1914 return (0);
1918 OP_rm (bytemode)
1919 int bytemode;
1921 switch (bytemode)
1923 case d_mode:
1924 oappend (names32[rm]);
1925 break;
1926 case w_mode:
1927 oappend (names16[rm]);
1928 break;
1930 return (0);
1933 #define MAXLEN 20
1936 print_insn (realmemaddr, memaddr, stream, addrlen)
1937 CORE_ADDR memaddr, realmemaddr;
1938 FILE *stream;
1939 int addrlen;
1941 unsigned char buffer[MAXLEN];
1943 if(addrlen == 32){
1944 dflag = 1;
1945 aflag = 1;
1946 } else {
1947 dflag = 0;
1948 aflag = 0;
1952 read_memory (memaddr, (char *) buffer, MAXLEN);
1954 return (i386dis ((int)realmemaddr, buffer, stream));