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