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