00001
00002
00003
00004
00005
00006 #include "mdb.h"
00007 #include <stddef.h>
00008 #include <stdio.h>
00009 #include <sys/types.h>
00010 #include "proto.h"
00011
00012 struct address_s
00013 {
00014 off_t off;
00015 off_t base;
00016 };
00017
00018 PRIVATE int bits32;
00019 PRIVATE struct address_s uptr;
00020
00021 FORWARD _PROTOTYPE( u8_t get8, (void) );
00022 FORWARD _PROTOTYPE( u16_t get16, (void) );
00023 FORWARD _PROTOTYPE( u32_t get32, (void) );
00024 FORWARD _PROTOTYPE( u8_t peek_byte, (off_t addr) );
00025 FORWARD _PROTOTYPE( u16_t peek_word, (off_t addr) );
00026 FORWARD _PROTOTYPE( int puti, (void) );
00027 FORWARD _PROTOTYPE( int outsegaddr, (struct address_s *addr) );
00028 FORWARD _PROTOTYPE( int outssegaddr, (struct address_s *addr) );
00029 FORWARD _PROTOTYPE( int show1instruction , (void));
00030
00031
00032
00033
00034 #define LINDIRECT '['
00035 #define RINDIRECT ']'
00036
00037 #define BASE_MASK 0x07
00038 #define INDEX_MASK 0x38
00039 #define INDEX_SHIFT 3
00040 #define MOD_MASK 0xC0
00041 #define REG_MOD 0xC0
00042 #define MEM0_MOD 0x00
00043 #define MEM1_MOD 0x40
00044 #define MEM2_MOD 0x80
00045 #define REG_MASK 0x38
00046 #define REG_SHIFT 3
00047 #define RM_MASK 0x07
00048 #define RM_SHIFT 0
00049 #define SS_MASK 0xC0
00050 #define SS_SHIFT 6
00051
00052 #define SIGNBIT 0x02
00053 #define WORDBIT 0x01
00054 #define TOREGBIT 0x02
00055
00056 #define MAX_SIGNED_CHAR 0x7F
00057 #define MAX_UNSIGNED_CHAR 0xFF
00058
00059 typedef unsigned opcode_pt;
00060
00061 typedef int reg_pt;
00062 typedef int su16_t;
00063 typedef int su8_pt;
00064
00065 FORWARD _PROTOTYPE( su8_pt get8s , (void));
00066 FORWARD _PROTOTYPE( void getmodregrm , (void));
00067 FORWARD _PROTOTYPE( void i_00_to_3f , (opcode_pt opc ));
00068 FORWARD _PROTOTYPE( void i_40_to_5f , (opcode_pt opc ));
00069 FORWARD _PROTOTYPE( void i_60_to_6f , (opcode_pt opc ));
00070 FORWARD _PROTOTYPE( void i_70_to_7f , (opcode_pt opc ));
00071 FORWARD _PROTOTYPE( void i_80 , (opcode_pt opc ));
00072 FORWARD _PROTOTYPE( void i_88 , (opcode_pt opc ));
00073 FORWARD _PROTOTYPE( void i_90 , (opcode_pt opc ));
00074 FORWARD _PROTOTYPE( void i_98 , (opcode_pt opc ));
00075 FORWARD _PROTOTYPE( void i_a0 , (opcode_pt opc ));
00076 FORWARD _PROTOTYPE( void i_a8 , (opcode_pt opc ));
00077 FORWARD _PROTOTYPE( void i_b0 , (opcode_pt opc ));
00078 FORWARD _PROTOTYPE( void i_b8 , (opcode_pt opc ));
00079 FORWARD _PROTOTYPE( void i_c0 , (opcode_pt opc ));
00080 FORWARD _PROTOTYPE( void i_c8 , (opcode_pt opc ));
00081 FORWARD _PROTOTYPE( void i_d0 , (opcode_pt opc ));
00082 FORWARD _PROTOTYPE( void i_d8 , (opcode_pt opc ));
00083 FORWARD _PROTOTYPE( void i_e0 , (opcode_pt opc ));
00084 FORWARD _PROTOTYPE( void i_e8 , (opcode_pt opc ));
00085 FORWARD _PROTOTYPE( void i_f0 , (opcode_pt opc ));
00086 FORWARD _PROTOTYPE( void i_f8 , (opcode_pt opc ));
00087 FORWARD _PROTOTYPE( void outad , (opcode_pt opc ));
00088 FORWARD _PROTOTYPE( void outad1 , (opcode_pt opc ));
00089 FORWARD _PROTOTYPE( void outalorx , (opcode_pt opc ));
00090 FORWARD _PROTOTYPE( void outax , (void));
00091 FORWARD _PROTOTYPE( void outbptr , (void));
00092 FORWARD _PROTOTYPE( void outbwptr , (opcode_pt opc ));
00093 FORWARD _PROTOTYPE( void outea , (opcode_pt wordflags ));
00094 FORWARD _PROTOTYPE( void outf1 , (void));
00095 FORWARD _PROTOTYPE( void out32offset , (void));
00096 FORWARD _PROTOTYPE( void outfishy , (void));
00097 FORWARD _PROTOTYPE( void outgetaddr , (void));
00098 FORWARD _PROTOTYPE( void outimmed , (opcode_pt signwordflag ));
00099 FORWARD _PROTOTYPE( void outpc , (off_t pc ));
00100 FORWARD _PROTOTYPE( void outsegpc , (void));
00101 FORWARD _PROTOTYPE( void oututstr , (char *s ));
00102 FORWARD _PROTOTYPE( void outword , (void));
00103 FORWARD _PROTOTYPE( void outwptr , (void));
00104 FORWARD _PROTOTYPE( void outwsize , (void));
00105 FORWARD _PROTOTYPE( void pagef , (void));
00106 FORWARD _PROTOTYPE( void shift , (opcode_pt opc ));
00107 FORWARD _PROTOTYPE( void checkmemory , (void));
00108 FORWARD _PROTOTYPE( void CL , (void));
00109 FORWARD _PROTOTYPE( void Eb , (void));
00110 FORWARD _PROTOTYPE( void Ev , (void));
00111 FORWARD _PROTOTYPE( void EvGv , (void));
00112 FORWARD _PROTOTYPE( void EvIb , (void));
00113 FORWARD _PROTOTYPE( void Ew , (void));
00114 FORWARD _PROTOTYPE( void EwRw , (void));
00115 FORWARD _PROTOTYPE( void Gv , (void));
00116 FORWARD _PROTOTYPE( void Gv1 , (void));
00117 FORWARD _PROTOTYPE( void GvEv , (void));
00118 FORWARD _PROTOTYPE( void GvEw , (void));
00119 FORWARD _PROTOTYPE( void GvM , (void));
00120 FORWARD _PROTOTYPE( void GvMa , (void));
00121 FORWARD _PROTOTYPE( void GvMp , (void));
00122 FORWARD _PROTOTYPE( void Ib , (void));
00123 FORWARD _PROTOTYPE( void Iw , (void));
00124 FORWARD _PROTOTYPE( void Iv , (void));
00125 FORWARD _PROTOTYPE( void Jb , (void));
00126 FORWARD _PROTOTYPE( void Jv , (void));
00127 FORWARD _PROTOTYPE( void Ms , (void));
00128
00129 _PROTOTYPE( typedef void (*pfv_t),(opcode_pt opc ));
00130
00131 PRIVATE pfv_t optable[] =
00132 {
00133 i_00_to_3f,
00134 i_00_to_3f,
00135 i_00_to_3f,
00136 i_00_to_3f,
00137 i_00_to_3f,
00138 i_00_to_3f,
00139 i_00_to_3f,
00140 i_00_to_3f,
00141 i_40_to_5f,
00142 i_40_to_5f,
00143 i_40_to_5f,
00144 i_40_to_5f,
00145 i_60_to_6f,
00146 i_60_to_6f,
00147 i_70_to_7f,
00148 i_70_to_7f,
00149 i_80,
00150 i_88,
00151 i_90,
00152 i_98,
00153 i_a0,
00154 i_a8,
00155 i_b0,
00156 i_b8,
00157 i_c0,
00158 i_c8,
00159 i_d0,
00160 i_d8,
00161 i_e0,
00162 i_e8,
00163 i_f0,
00164 i_f8,
00165 };
00166
00167 PRIVATE char fishy[] = "???";
00168 PRIVATE char movtab[] = "mov\t";
00169
00170 PRIVATE char *genreg[] =
00171 {
00172 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
00173 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
00174 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
00175 };
00176
00177 PRIVATE char *segreg[] =
00178 {
00179 "es", "cs", "ss", "ds", "fs", "gs", "?s", "?s",
00180 };
00181
00182 PRIVATE char *indreg[] =
00183 {
00184 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx",
00185 };
00186
00187 PRIVATE char *str_00_to_3f[] =
00188 {
00189
00190 "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp",
00191 };
00192
00193 PRIVATE char *sstr_00_to_3f[] =
00194 {
00195
00196 "push\tes", "pop\tes", "push\tcs", "pop\tcs",
00197 "push\tss", "pop\tss", "push\tds", "pop\tds",
00198 "es:", "daa", "cs:", "das", "ss:", "aaa", "ds:", "aas",
00199 };
00200
00201 PRIVATE char *sstr_0f[] =
00202 {
00203 "push\tfs", "pop\tfs", fishy, "bt\t", "shld\t", "shld\t", fishy, fishy,
00204 "push\tgs", "pop\tgs", fishy, "bts\t", "shrd\t", "shrd\t", fishy, "imul\t",
00205 fishy, fishy, "lss\t", "btr\t", "lfs\t", "lgs\t", "movzx\t", "movzx\t",
00206 fishy, fishy, "", "btc\t", "bsf\t", "bsr\t", "movsx\t", "movsx\t",
00207 };
00208
00209 PRIVATE char *ssstr_0f[] =
00210 {
00211 "sldt\t", "str\t", "lldt\t", "ltr\t", "verr\t", "verw\t", fishy, fishy,
00212 "sgdt\t", "sidt\t", "lgdt\t", "lidt\t", "smsw\t", fishy, "lmsw\t", fishy,
00213 fishy, fishy, fishy, fishy, "bt\t", "bts\t", "btr\t", "btc\t",
00214 };
00215
00216 PRIVATE char *str_40_to_5f[] =
00217 {
00218
00219 "inc\t", "dec\t", "push\t", "pop\t",
00220 };
00221
00222 PRIVATE char *str_60_to_6f[] =
00223 {
00224 "pusha", "popa", "bound\t", "arpl\t", "fs:", "gs:", "os:", "as:",
00225 "push\t", "imul\t", "push\t", "imul\t", "insb", "ins", "outsb", "outs",
00226 };
00227
00228 PRIVATE char *str_flags[] =
00229 {
00230
00231 "o", "no", "b", "nb", "z", "nz", "be", "a",
00232 "s", "ns", "pe", "po", "l", "ge", "le", "g",
00233 };
00234
00235 PRIVATE char *str_98[] =
00236 {
00237 "cbw", "cwd", "call\t", "wait", "pushf", "popf", "sahf", "lahf",
00238 "cwde", "cdq", "call\t", "wait", "pushfd", "popfd", "sahf", "lahf",
00239 };
00240
00241 PRIVATE char *str_a0[] =
00242 {
00243 movtab, movtab, movtab, movtab, "movsb", "movs", "cmpsb", "cmps",
00244 };
00245
00246 PRIVATE char *str_a8[] =
00247 {
00248 "test\t", "test\t", "stosb", "stos", "lodsb", "lods", "scasb", "scas",
00249 };
00250
00251 PRIVATE char *str_c0[] =
00252 {
00253 "", "", "ret\t", "ret", "les\t", "lds\t", movtab, movtab,
00254 };
00255
00256 PRIVATE char *str_c8[] =
00257 {
00258 "enter\t", "leave", "retf\t", "retf", "int\t3", "int\t", "into", "iret",
00259 };
00260
00261 PRIVATE char *str_d0[] =
00262 {
00263 "aam", "aad", "db\td6", "xlat",
00264 };
00265
00266 PRIVATE char *sstr_d0[] =
00267 {
00268 "rol", "ror", "rcl", "rcr", "shl", "shr", fishy, "sar",
00269 };
00270
00271 PRIVATE char *str_d8[] =
00272 {
00273 "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr",
00274 "fld", NULL, "fst", "fstp", "fldenv", "fldcw", "fstenv", "fstcw",
00275 "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr",
00276 "fild", NULL, "fist", "fistp", NULL, "fld", NULL, "fstp",
00277 "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr",
00278 "fld", NULL, "fst", "fstp", "frstor", NULL, "fsave", "fstsw",
00279 "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr",
00280 "fild", NULL, "fist", "fistp", "fbld", "fild", "fbstp", "fistp",
00281 };
00282
00283 PRIVATE char *str1_d8[] =
00284 {
00285 "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr",
00286 "fld", "fxch", "\0\0", NULL, "\0\10", "\0\20", "\0\30", "\0\40",
00287 NULL, NULL, NULL, NULL, NULL, "\0\50", NULL, NULL,
00288 NULL, NULL, NULL, NULL, "\0\60", NULL, NULL, NULL,
00289 "fadd", "fmul", NULL, NULL, "fsubr", "fsub", "fdivr", "fdiv",
00290 "ffree", NULL, "fst", "fstp", "fucom", "fucomp", NULL, NULL,
00291 "faddp", "fmulp", NULL, "\0\70", "fsubrp", "fsubp", "fdivrp", "fdivp",
00292 NULL, NULL, NULL, NULL, "\0\100", NULL, NULL, NULL,
00293 };
00294
00295 PRIVATE unsigned char size_d8[] =
00296 {
00297 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 14-28, 2, 14-28, 2,
00298 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 0, 10, 0, 10,
00299 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 8, 94-108, 0, 94-108, 2,
00300 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 10, 8, 10, 8,
00301 };
00302
00303 PRIVATE char *sstr_d8[] =
00304 {
00305 "fnop", NULL, NULL, NULL,
00306 NULL, NULL, NULL, NULL,
00307 "fchs", "fabs", NULL, NULL,
00308 "ftst", "fxam", NULL, NULL,
00309 "fld1", "fldl2t", "fldl2e", "fldpi",
00310 "fldlg2", "fldln2", "fldz", NULL,
00311 "f2xm1", "fyl2x", "fptan", "fpatan",
00312 "fxtract", "fprem1", "fdecstp", "fincstp",
00313 "fprem", "fyl2xp1", "fsqrt", "fsincos",
00314 "frndint", "fscale", "fsin", "fcos",
00315 NULL, "fucompp", NULL, NULL,
00316 NULL, NULL, NULL, NULL,
00317 "feni", "fdisi", "fclex", "finit",
00318 "fsetpm", NULL, NULL, NULL,
00319 NULL, "fcompp", NULL, NULL,
00320 NULL, NULL, NULL, NULL,
00321 NULL, NULL, NULL, NULL,
00322 "fstsw\tax", NULL, NULL, NULL,
00323 };
00324
00325 PRIVATE char *str_e0[] =
00326 {
00327 "loopnz\t", "loopz\t", "loop\t", "jcxz\t",
00328 "in\t", "in\t", "out\t", "out\t",
00329 };
00330
00331 PRIVATE char *str_e8[] =
00332 {
00333 "call\t", "jmp\t", "jmp\t", "jmp\t",
00334 "in\t", "in\t", "out\t", "out\t",
00335 };
00336
00337 PRIVATE char *str_f0[] =
00338 {
00339 "lock\t", "db\tf1", "repnz\t", "repz\t",
00340 "hlt", "cmc",
00341
00342 };
00343
00344 PRIVATE char *sstr_f0[] =
00345 {
00346 "test\t", fishy, "not\t", "neg\t",
00347 "mul\t", "imul\t", "div\t", "idiv\t",
00348 };
00349
00350 PRIVATE char *str_f8[] =
00351 {
00352 "clc", "stc", "cli", "sti",
00353 "cld", "std",
00354
00355 };
00356
00357 PRIVATE char *sstr_f8[] =
00358 {
00359 "inc\t", "dec\t", "call\t", "call\tfar ",
00360 "jmp\t", "jmp\tfar ", "push\t", "???\t",
00361 };
00362
00363 PRIVATE int data_seg;
00364 PRIVATE unsigned hasize;
00365 PRIVATE unsigned hdefsize;
00366 PRIVATE unsigned hosize;
00367
00368 PRIVATE opcode_pt mod;
00369 PRIVATE off_t offtable[2];
00370 PRIVATE off_t *offptr;
00371 PRIVATE off_t *off1ptr;
00372 PRIVATE opcode_pt reg;
00373 PRIVATE opcode_pt rm;
00374
00375 PRIVATE su8_pt get8s()
00376 {
00377 u8_t got;
00378
00379 if ((got = get8()) > MAX_SIGNED_CHAR)
00380 got -= (MAX_UNSIGNED_CHAR + 1);
00381 return got;
00382 }
00383
00384 PRIVATE void getmodregrm()
00385 {
00386 opcode_pt modregrm;
00387
00388 modregrm = get8();
00389 mod = modregrm & MOD_MASK;
00390 reg = (modregrm & REG_MASK) >> REG_SHIFT;
00391 rm = (modregrm & RM_MASK) >> RM_SHIFT;
00392 }
00393
00394 PRIVATE void i_00_to_3f(opc)
00395 opcode_pt opc;
00396 {
00397 opcode_pt sub;
00398
00399 if (opc == 15)
00400 pagef();
00401 else if ((sub = opc & 7) >= 6)
00402 {
00403 outustr((sstr_00_to_3f - 6)[((opc >> 2) & 0x0E) + sub]);
00404 if (!(opc & 1))
00405 data_seg = opc;
00406 }
00407 else
00408 {
00409 oututstr(str_00_to_3f[(opc >> 3) & 7]);
00410 if (sub == 4)
00411 {
00412 outustr(genreg[0]);
00413 outcomma();
00414 Ib();
00415 }
00416 else if (sub == 5)
00417 {
00418 outax();
00419 outcomma();
00420 Iv();
00421 }
00422 else
00423 outad(sub);
00424 }
00425 }
00426
00427 PRIVATE void i_40_to_5f(opc)
00428 opcode_pt opc;
00429 {
00430 outustr(str_40_to_5f[(opc >> 3) & 3]);
00431 outustr(genreg[hosize + (opc & 7)]);
00432 }
00433
00434 PRIVATE void i_60_to_6f(opc)
00435 opcode_pt opc;
00436 {
00437
00438
00439 outustr((str_60_to_6f - 0x60)[opc]);
00440 switch (opc)
00441 {
00442 case 0x60:
00443 case 0x61:
00444 if (hosize == 16)
00445 outwsize();
00446 break;
00447 case 0x62:
00448 GvMa();
00449 break;
00450 case 0x63:
00451 EwRw();
00452 break;
00453 case 0x64:
00454 case 0x65:
00455 data_seg = opc;
00456 break;
00457 case 0x66:
00458 hosize = (16 + 8) - hdefsize;
00459 break;
00460 case 0x67:
00461 hasize = (16 + 8) - hdefsize;
00462 break;
00463 case 0x68:
00464 outword();
00465 Iv();
00466 break;
00467 case 0x6A:
00468 outword();
00469 outimmed(SIGNBIT | WORDBIT);
00470 break;
00471 case 0x69:
00472 GvEv();
00473 outcomma();
00474 Iv();
00475 break;
00476 case 0x6B:
00477 GvEv();
00478 outcomma();
00479 outimmed(SIGNBIT | WORDBIT);
00480 break;
00481 case 0x6D:
00482 case 0x6F:
00483 outwsize();
00484 break;
00485 }
00486 }
00487
00488 PRIVATE void i_70_to_7f(opc)
00489 opcode_pt opc;
00490 {
00491 outustr("j");
00492 oututstr((str_flags - 0x70)[opc]);
00493 Jb();
00494 }
00495
00496 PRIVATE void i_80(opc)
00497 opcode_pt opc;
00498 {
00499 if (opc >= 4)
00500 {
00501 outustr(opc >= 6 ? "xchg\t" : "test\t");
00502 outad(opc);
00503 }
00504 else
00505 {
00506 getmodregrm();
00507 oututstr(str_00_to_3f[reg]);
00508 outbwptr(opc);
00509 outea(opc);
00510 outcomma();
00511 outimmed(opc);
00512 #ifdef SIGNED_LOGICALS
00513 if (opc & SIGNBIT && (reg == 1 || reg == 4 || reg == 6))
00514
00515
00516
00517 outfishy();
00518 #endif
00519 }
00520 }
00521
00522 PRIVATE void i_88(opc)
00523 opcode_pt opc;
00524 {
00525 if (opc < 4)
00526 {
00527 outustr(movtab);
00528 outad(opc);
00529 }
00530 else if (opc == 5)
00531 {
00532 oututstr("lea");
00533 GvM();
00534 }
00535 else if (opc == 7)
00536 {
00537 oututstr("pop");
00538 getmodregrm();
00539 outwptr();
00540 Ev();
00541 if (reg != 0)
00542 outfishy();
00543 }
00544 else
00545 {
00546 getmodregrm();
00547 outustr(movtab);
00548 if (!(opc & TOREGBIT))
00549 {
00550 Ev();
00551 outcomma();
00552 }
00553 outustr(segreg[reg]);
00554 if (opc & TOREGBIT)
00555 {
00556 outcomma();
00557 Ev();
00558 }
00559 }
00560 }
00561
00562 PRIVATE void i_90(opc)
00563 opcode_pt opc;
00564 {
00565 if (opc == 0)
00566 outustr("nop");
00567 else
00568 {
00569 outustr("xchg\t");
00570 outax();
00571 outcomma();
00572 outustr(genreg[hosize + opc]);
00573 }
00574 }
00575
00576 PRIVATE void i_98(opc)
00577 opcode_pt opc;
00578 {
00579 outustr((str_98 - 8)[opc + hosize]);
00580 if (opc == 2)
00581 outsegpc();
00582 }
00583
00584 PRIVATE void i_a0(opc)
00585 opcode_pt opc;
00586 {
00587 outustr(str_a0[opc]);
00588 if (opc < 4)
00589 {
00590 mod = MEM0_MOD;
00591 reg = 0;
00592 if (hasize == 16)
00593 rm = 5;
00594 else
00595 rm = 6;
00596 outad1(opc ^ TOREGBIT);
00597 }
00598 else if (opc & 1)
00599 outwsize();
00600 }
00601
00602 PRIVATE void i_a8(opc)
00603 opcode_pt opc;
00604 {
00605 outustr(str_a8[opc]);
00606 if (opc < 2)
00607 {
00608 outalorx(opc);
00609 outcomma();
00610 outimmed(opc);
00611 }
00612 else if (opc & 1)
00613 outwsize();
00614 }
00615
00616 PRIVATE void i_b0(opc)
00617 opcode_pt opc;
00618 {
00619 outustr(movtab);
00620 outustr(genreg[opc]);
00621 outcomma();
00622 Ib();
00623 }
00624
00625 PRIVATE void i_b8(opc)
00626 opcode_pt opc;
00627 {
00628 outustr(movtab);
00629 outustr(genreg[hosize + opc]);
00630 outcomma();
00631 Iv();
00632 }
00633
00634 PRIVATE void i_c0(opc)
00635 opcode_pt opc;
00636 {
00637 outustr(str_c0[opc]);
00638 if (opc >= 6)
00639 {
00640 getmodregrm();
00641 outbwptr(opc);
00642 outea(opc);
00643 outcomma();
00644 outimmed(opc & WORDBIT);
00645 if (reg != 0)
00646
00647 outfishy();
00648 }
00649 else if (opc >= 4)
00650 GvMp();
00651 else if (opc == 2)
00652 Iv();
00653 else if (opc < 2)
00654 shift(opc);
00655 }
00656
00657 PRIVATE void i_c8(opc)
00658 opcode_pt opc;
00659 {
00660 outustr(str_c8[opc]);
00661 if (opc == 0)
00662 {
00663 Iw();
00664 outcomma();
00665 Ib();
00666 }
00667 if (opc == 2)
00668 Iv();
00669 else if (opc == 5)
00670 Ib();
00671 else if (opc == 7 && hosize == 16)
00672 outwsize();
00673 }
00674
00675 PRIVATE void i_d0(opc)
00676 opcode_pt opc;
00677 {
00678 opcode_pt aabyte;
00679
00680 if (opc < 4)
00681 shift(opc | 0xD0);
00682 else
00683 {
00684 outustr((str_d0 - 4)[opc]);
00685 if (opc < 6 && (aabyte = get8()) != 0x0A)
00686 {
00687 outtab();
00688 outh8(aabyte);
00689 outfishy();
00690 }
00691 }
00692 }
00693
00694 PRIVATE void i_d8(opc)
00695 opcode_pt opc;
00696 {
00697 opcode_pt esc;
00698 char *str;
00699
00700 getmodregrm();
00701 esc = (opc << 3) | reg;
00702 if ((str = (mod == REG_MOD ? str1_d8 : str_d8)[esc]) == NULL)
00703 {
00704 escape:
00705 oututstr("esc");
00706 outh8(esc);
00707 outcomma();
00708 outea(0);
00709 return;
00710 }
00711 if (*str == 0)
00712 {
00713 str = sstr_d8[str[1] + rm];
00714 if (str == NULL)
00715 goto escape;
00716 outustr(str);
00717 return;
00718 }
00719 outustr(str);
00720 outtab();
00721 if (mod == REG_MOD)
00722 {
00723 if (opc == 0 && reg != 2 && reg != 3)
00724 outustr("st,");
00725 outf1();
00726 if (opc == 4 || opc == 6)
00727 outustr(",st");
00728 return;
00729 }
00730 switch(size_d8[esc])
00731 {
00732 case 4:
00733 outustr("d");
00734 case 2:
00735 outwptr();
00736 break;
00737 case 8:
00738 outustr("q");
00739 outwptr();
00740 break;
00741 case 10:
00742 outustr("t");
00743 outbptr();
00744 break;
00745 }
00746 outea(opc);
00747 }
00748
00749 PRIVATE void i_e0(opc)
00750 opcode_pt opc;
00751 {
00752 outustr(str_e0[opc]);
00753 if (opc < 4)
00754 Jb();
00755 else if (opc < 6)
00756 {
00757 outalorx(opc);
00758 outcomma();
00759 Ib();
00760 }
00761 else
00762 {
00763 Ib();
00764 outcomma();
00765 outalorx(opc);
00766 }
00767 }
00768
00769 PRIVATE void i_e8(opc)
00770 opcode_pt opc;
00771 {
00772 outustr(str_e8[opc]);
00773 if (opc < 2)
00774 Jv();
00775 else if (opc == 2)
00776 outsegpc();
00777 else if (opc == 3)
00778 Jb();
00779 else
00780 {
00781 if (opc & TOREGBIT)
00782 {
00783 outustr(genreg[10]);
00784 outcomma();
00785 outalorx(opc);
00786 }
00787 else
00788 {
00789 outalorx(opc);
00790 outcomma();
00791 outustr(genreg[10]);
00792 }
00793 }
00794 }
00795
00796 PRIVATE void i_f0(opc)
00797 opcode_pt opc;
00798 {
00799 if (opc < 6)
00800 outustr(str_f0[opc]);
00801 else
00802 {
00803 getmodregrm();
00804 outustr(sstr_f0[reg]);
00805 outbwptr(opc);
00806 outea(opc);
00807 if (reg == 0)
00808 {
00809 outcomma();
00810 outimmed(opc & WORDBIT);
00811 }
00812 }
00813 }
00814
00815 PRIVATE void i_f8(opc)
00816 opcode_pt opc;
00817 {
00818 if (opc < 6)
00819 outustr(str_f8[opc]);
00820 else
00821 {
00822 getmodregrm();
00823 if (opc == 6 && reg >= 2)
00824 outustr("fishy\t");
00825 else
00826 outustr(sstr_f8[reg]);
00827 outbwptr(opc);
00828 outea(opc);
00829 }
00830 }
00831
00832 PRIVATE void outad(opc)
00833 opcode_pt opc;
00834 {
00835 getmodregrm();
00836 outad1(opc);
00837 }
00838
00839 PRIVATE void outad1(opc)
00840 opcode_pt opc;
00841 {
00842 if (!(opc & TOREGBIT))
00843 {
00844 outea(opc);
00845 outcomma();
00846 }
00847 if (opc & WORDBIT)
00848 Gv1();
00849 else
00850 outustr(genreg[reg]);
00851 if (opc & TOREGBIT)
00852 {
00853 outcomma();
00854 outea(opc);
00855 }
00856 }
00857
00858 PRIVATE void outalorx(opc)
00859 opcode_pt opc;
00860 {
00861 if (opc & WORDBIT)
00862 outax();
00863 else
00864 outustr(genreg[0]);
00865 }
00866
00867 PRIVATE void outax()
00868 {
00869 outustr(genreg[hosize]);
00870 }
00871
00872 PRIVATE void outbptr()
00873 {
00874 outustr("byte ptr ");
00875 }
00876
00877 PRIVATE void outbwptr(opc)
00878 opcode_pt opc;
00879 {
00880 if (mod != REG_MOD)
00881 {
00882 if (opc & WORDBIT)
00883 outwptr();
00884 else
00885 outbptr();
00886 }
00887 }
00888
00889 PRIVATE void outea(wordflags)
00890 opcode_pt wordflags;
00891 {
00892 reg_pt base;
00893 reg_pt index;
00894 opcode_pt ss;
00895 opcode_pt ssindexbase;
00896
00897 if (mod == REG_MOD)
00898 outustr(genreg[hosize * (wordflags & WORDBIT) + rm]);
00899 else
00900 {
00901 outbyte(LINDIRECT);
00902 if (hasize == 16)
00903 {
00904 if (rm == 4)
00905 {
00906 base = (ssindexbase = get8()) & BASE_MASK;
00907 if (mod == MEM0_MOD && base == 5)
00908 outgetaddr();
00909 else
00910 outustr((genreg + 16)[base]);
00911 ss = (ssindexbase & SS_MASK) >> SS_SHIFT;
00912 if ((index = (ssindexbase & INDEX_MASK) >> INDEX_SHIFT) != 4)
00913 {
00914 outbyte('+');
00915 outustr((genreg + 16)[index]);
00916 outstr("\0\0\0*2\0*4\0*8\0" + (3 * ss));
00917 }
00918 }
00919 else if (mod == MEM0_MOD && rm == 5)
00920 outgetaddr();
00921 else
00922 outustr((genreg + 16)[rm]);
00923 }
00924 else if (mod == MEM0_MOD && rm == 6)
00925 outgetaddr();
00926 else
00927 outustr(indreg[rm]);
00928 if (mod == MEM1_MOD)
00929
00930 outimmed(SIGNBIT | WORDBIT);
00931 else if (mod == MEM2_MOD)
00932 {
00933 outbyte('+');
00934 #if (_WORD_SIZE == 4)
00935 out32offset();
00936 #else
00937 outgetaddr();
00938 #endif
00939 }
00940 outbyte(RINDIRECT);
00941 if (hasize == 16 && rm == 4 && index == 4 && ss != 0)
00942 outfishy();
00943 }
00944 }
00945
00946 PRIVATE void outf1()
00947 {
00948 outustr("st(");
00949 outbyte((int) (rm + '0'));
00950 outbyte(')');
00951 }
00952
00953 #if (_WORD_SIZE == 4)
00954
00955 PRIVATE void out32offset()
00956 {
00957 off_t off;
00958
00959 if (hasize == 16)
00960 off = get32();
00961 else
00962 outfishy();
00963
00964 outh32(off);
00965 }
00966 #endif
00967
00968 PRIVATE void outfishy()
00969 {
00970 outustr("\t???");
00971 }
00972
00973 PRIVATE void outgetaddr()
00974 {
00975 off_t off;
00976
00977 if (hasize == 16)
00978 off = get32();
00979 else
00980 off = get16();
00981
00982 if ( finds_data(off,data_seg) )
00983 *offptr++ = off;
00984 else if (hasize == 16)
00985 outh32(off);
00986 else
00987 outh16((u16_t) off);
00988 }
00989
00990 PRIVATE void outimmed(signwordflag)
00991 opcode_pt signwordflag;
00992 {
00993 su8_pt byte;
00994
00995 if (signwordflag & WORDBIT)
00996 {
00997 if (signwordflag & SIGNBIT)
00998 {
00999 if ((byte = get8s()) < 0)
01000 {
01001 outbyte('-');
01002 byte = -byte;
01003 }
01004 else
01005 outbyte('+');
01006 outh8((u8_t) byte);
01007 }
01008 else
01009 Iv();
01010 }
01011 else
01012 Ib();
01013 }
01014
01015 PRIVATE void outpc(pc)
01016 off_t pc;
01017 {
01018 if (hosize == 8)
01019 pc = (u16_t) pc;
01020
01021 if ( finds_pc(pc) )
01022 *offptr++ = pc;
01023 else if (hosize == 16)
01024 outh32(pc);
01025 else
01026 outh16((u16_t) pc);
01027 }
01028
01029 PRIVATE void outsegpc()
01030 {
01031 off_t oldbase;
01032 off_t pc;
01033
01034 if (hosize == 16)
01035 pc = get32();
01036 else
01037 pc = get16();
01038 oldbase = uptr.base;
01039 outh16((u16_t) (uptr.base = get16()));
01040
01041 outbyte(':');
01042 outpc(pc);
01043 uptr.base = oldbase;
01044 }
01045
01046 PRIVATE void oututstr(s)
01047 char *s;
01048 {
01049 outustr(s);
01050 outtab();
01051 }
01052
01053 PRIVATE void outword()
01054 {
01055 outustr("dword " + ((16 - hosize) >> 3));
01056 }
01057
01058 PRIVATE void outwptr()
01059 {
01060 outword();
01061 outustr("ptr ");
01062 }
01063
01064 PRIVATE void outwsize()
01065 {
01066 if (hosize == 16)
01067 outustr("d");
01068 else
01069 outustr("w");
01070 }
01071
01072 PRIVATE void pagef()
01073 {
01074 opcode_pt opc;
01075 int regbad;
01076
01077 if ((opc = get8()) <= 1 || opc == 0xBA)
01078 {
01079 if (opc == 0xBA)
01080 opc = 16;
01081 else
01082 opc *= 8;
01083 getmodregrm();
01084 outustr(ssstr_0f[opc += reg]);
01085 if (opc < 6 || opc == 12 || opc == 14)
01086 Ew();
01087 else if (opc >= 8 && opc < 13)
01088 Ms();
01089 else if (opc >= 20)
01090 {
01091 outbwptr(WORDBIT);
01092 EvIb();
01093 }
01094 }
01095 else if (opc < 4)
01096 {
01097 oututstr("lar\0lsl" + 4 * (opc - 2));
01098 GvEw();
01099 }
01100 else if (opc == 5)
01101 {
01102 outustr("loadall");
01103 outfishy();
01104 }
01105 else if (opc == 6)
01106 outustr("clts");
01107 else if (opc < 0x20)
01108 outstr(fishy);
01109 else if (opc < 0x27 && opc != 0x25)
01110 {
01111 outustr(movtab);
01112 getmodregrm();
01113 hosize = 16;
01114 if (!(opc & TOREGBIT))
01115 {
01116 Ev();
01117 outcomma();
01118 }
01119 regbad = FALSE;
01120 if (opc & 1)
01121 {
01122 outustr("dr");
01123 if (reg == 4 || reg == 5)
01124 regbad = TRUE;
01125 }
01126 else if (opc < 0x24)
01127 {
01128 outustr("cr");
01129 if (reg >= 4 || reg == 1)
01130 regbad = TRUE;
01131 }
01132 else
01133 {
01134 outustr("tr");
01135 if (reg < 6)
01136 regbad = TRUE;
01137 }
01138 outbyte((int) (reg + '0'));
01139 if (opc & TOREGBIT)
01140 {
01141 outcomma();
01142 Ev();
01143 }
01144 if (regbad || mod != REG_MOD)
01145 outfishy();
01146 }
01147 else if (opc < 0x80)
01148 outstr(fishy);
01149 else if (opc < 0x90)
01150 {
01151 outustr("j");
01152 oututstr((str_flags - 0x80)[opc]);
01153 Jv();
01154 }
01155 else if (opc < 0xA0)
01156 {
01157 outustr("set");
01158 oututstr((str_flags - 0x90)[opc]);
01159 getmodregrm();
01160 outbwptr(0);
01161 Eb();
01162 }
01163 else if (opc < 0xC0)
01164 {
01165 outustr((sstr_0f - 0xA0)[opc]);
01166 switch (opc)
01167 {
01168 case 0xA3:
01169 case 0xAB:
01170 case 0xB3:
01171 case 0xBB:
01172 EvGv();
01173 break;
01174 case 0xA4:
01175 case 0xAC:
01176 EvGv();
01177 outcomma();
01178 Ib();
01179 break;
01180 case 0xA5:
01181 case 0xAD:
01182 EvGv();
01183 outcomma();
01184 CL();
01185 break;
01186 case 0xAF:
01187 case 0xBC:
01188 case 0xBD:
01189 GvEv();
01190 break;
01191 case 0xB2:
01192 case 0xB4:
01193 case 0xB5:
01194 GvMp();
01195 break;
01196 case 0xB6:
01197 case 0xBE:
01198 Gv();
01199 outcomma();
01200 outbwptr(opc);
01201 Eb();
01202 break;
01203 case 0xB7:
01204 case 0xBF:
01205 Gv();
01206 outcomma();
01207 hosize = 8;
01208 outbwptr(opc);
01209 Ew();
01210 break;
01211 }
01212 }
01213 else
01214 outstr(fishy);
01215 }
01216
01217 PRIVATE int puti()
01218 {
01219 static int hadprefix;
01220 opcode_pt opcode;
01221
01222 more:
01223 offptr = offtable;
01224 opcode = get8();
01225 if (!hadprefix)
01226 {
01227 data_seg = DSEG;
01228 hdefsize = 8;
01229 if (bits32)
01230 hdefsize = 16;
01231 hosize =
01232 hasize = hdefsize;
01233 }
01234 (*optable[opcode >> 3])(opcode < 0x80 ? opcode : opcode & 7);
01235 if (offptr > offtable)
01236 {
01237 if (stringtab() >= 31)
01238 {
01239 outspace();
01240 outspace();
01241 }
01242 else
01243 while (stringtab() < 32)
01244 outtab();
01245 outbyte(';');
01246 for (off1ptr = offtable; off1ptr < offptr; ++off1ptr)
01247 {
01248 outspace();
01249 if (*off1ptr < 0x10000)
01250 outh16((u16_t) *off1ptr);
01251 else
01252 outh32(*off1ptr);
01253 }
01254 offptr = offtable;
01255 }
01256 if ((opcode & 0xE7) == 0x26 ||
01257 opcode >= 0x64 && opcode < 0x68 ||
01258 opcode == 0xF0 || opcode == 0xF2 || opcode == 0xF3)
01259
01260
01261
01262
01263
01264 {
01265 hadprefix = TRUE;
01266 goto more;
01267 return FALSE;
01268 }
01269 hadprefix = FALSE;
01270 return TRUE;
01271 }
01272
01273 PRIVATE void shift(opc)
01274 opcode_pt opc;
01275 {
01276 getmodregrm();
01277 oututstr(sstr_d0[reg]);
01278 outbwptr(opc);
01279 outea(opc);
01280 outcomma();
01281 if (opc < 0xD0)
01282 Ib();
01283 else if (opc & 2)
01284 CL();
01285 else
01286 outbyte('1');
01287 }
01288
01289 PRIVATE void checkmemory()
01290 {
01291 if (mod == REG_MOD)
01292 outfishy();
01293 }
01294
01295 PRIVATE void CL()
01296 {
01297 outustr(genreg[1]);
01298 }
01299
01300 PRIVATE void Eb()
01301 {
01302 outea(0);
01303 }
01304
01305 PRIVATE void Ev()
01306 {
01307 outea(WORDBIT);
01308 }
01309
01310 PRIVATE void EvGv()
01311 {
01312 getmodregrm();
01313 Ev();
01314 outcomma();
01315 Gv1();
01316 }
01317
01318 PRIVATE void EvIb()
01319 {
01320 Ev();
01321 outcomma();
01322 Ib();
01323 }
01324
01325 PRIVATE void Ew()
01326 {
01327 hosize = 8;
01328 Ev();
01329 }
01330
01331 PRIVATE void EwRw()
01332 {
01333 hosize = 8;
01334 EvGv();
01335 }
01336
01337 PRIVATE void Gv()
01338 {
01339 getmodregrm();
01340 Gv1();
01341 }
01342
01343 PRIVATE void Gv1()
01344 {
01345 outustr(genreg[hosize + reg]);
01346 }
01347
01348 PRIVATE void GvEv()
01349 {
01350 Gv();
01351 outcomma();
01352 Ev();
01353 }
01354
01355 PRIVATE void GvEw()
01356 {
01357 Gv();
01358 outcomma();
01359 Ew();
01360 }
01361
01362 PRIVATE void GvM()
01363 {
01364 GvEv();
01365 checkmemory();
01366 }
01367
01368 PRIVATE void GvMa()
01369 {
01370 GvM();
01371 }
01372
01373 PRIVATE void GvMp()
01374 {
01375 GvM();
01376 }
01377
01378 PRIVATE void Ib()
01379 {
01380 outh8(get8());
01381 }
01382
01383 PRIVATE void Iw()
01384 {
01385 outh16(get16());
01386 }
01387
01388 PRIVATE void Iv()
01389 {
01390 if (hosize == 16)
01391 outh32(get32());
01392 else
01393 Iw();
01394 }
01395
01396 PRIVATE void Jb()
01397 {
01398 off_t pcjump;
01399
01400 pcjump = get8s();
01401 outpc(pcjump + uptr.off);
01402 }
01403
01404 PRIVATE void Jv()
01405 {
01406 off_t pcjump;
01407
01408 if (hosize == 16)
01409 pcjump = get32();
01410 else
01411 pcjump = (su16_t) get16();
01412 outpc(pcjump + uptr.off);
01413 }
01414
01415 PRIVATE void Ms()
01416 {
01417 Ev();
01418 checkmemory();
01419 }
01420
01421
01422
01423 PUBLIC long dasm( addr, count, symflg )
01424 long addr;
01425 int count;
01426 int symflg;
01427 {
01428 #if (_WORD_SIZE == 4)
01429 bits32 = TRUE;
01430 #else
01431 bits32 = FALSE;
01432 #endif
01433 uptr.off = addr;
01434 uptr.base = 0;
01435 while ( count-- != 0 && show1instruction() )
01436 ;
01437 }
01438
01439
01440 PRIVATE int show1instruction()
01441 {
01442 register int column;
01443 int idone;
01444 static char line[81];
01445 int maxcol;
01446 struct address_s newuptr;
01447 struct address_s olduptr;
01448
01449 outbyte('\r');
01450 do
01451 {
01452 if ( text_symbol(uptr.off) ) {
01453 outbyte(':');
01454 outbyte('\n');
01455 }
01456 olduptr = uptr;
01457 openstring(line);
01458 idone = puti();
01459 line[stringpos()] = 0;
01460 closestring();
01461 newuptr = uptr;
01462 uptr = olduptr;
01463 column = outssegaddr(&uptr);
01464 while (uptr.off != newuptr.off)
01465 {
01466 outh8(get8());
01467 column += 2;
01468 }
01469 maxcol = bits32 ? 24 : 16;
01470 while (column < maxcol)
01471 {
01472 outtab();
01473 column += 8;
01474 }
01475 outtab();
01476 outstr(line);
01477 outbyte('\n');
01478 }
01479 while (!idone);
01480 return TRUE;
01481 }
01482
01483
01484 PRIVATE u8_t get8()
01485 {
01486
01487
01488 u8_t temp;
01489
01490 temp = peek_byte(uptr.off + uptr.base);
01491 ++uptr.off;
01492 return temp;
01493 }
01494
01495 PRIVATE u16_t get16()
01496 {
01497
01498
01499 u16_t temp;
01500
01501 temp = peek_word(uptr.off + uptr.base);
01502 uptr.off += 2;
01503 return temp;
01504 }
01505
01506 PRIVATE u32_t get32()
01507 {
01508
01509
01510 u32_t temp;
01511
01512 temp = peek_dword(uptr.off + uptr.base);
01513 uptr.off += 4;
01514 return temp;
01515 }
01516
01517
01518 PRIVATE int outsegaddr(addr)
01519 struct address_s *addr;
01520 {
01521
01522
01523 int bytes_printed;
01524
01525 bytes_printed = 2;
01526 bytes_printed = outsegreg(addr->base);
01527 if (bytes_printed > 4)
01528 outbyte('+');
01529 else
01530 outbyte(':');
01531 ++bytes_printed;
01532 if (addr->off >= 0x10000)
01533 {
01534 outh32(addr->off);
01535 return bytes_printed + 8;
01536 }
01537 outh16((u16_t) addr->off);
01538 return bytes_printed + 4;
01539 }
01540
01541 PRIVATE int outssegaddr(addr)
01542 struct address_s *addr;
01543 {
01544
01545
01546 int bytes_printed;
01547
01548 bytes_printed = outsegaddr(addr);
01549 outspace();
01550 outspace();
01551 return bytes_printed + 2;
01552 }
01553
01554 PRIVATE u8_t peek_byte(addr)
01555 off_t addr;
01556 {
01557 return (u8_t) peek_dword(addr) & 0xFF;
01558 }
01559
01560 PRIVATE u16_t peek_word(addr)
01561 off_t addr;
01562 {
01563 return (u16_t) peek_dword(addr);
01564 }