|
|
1.1 ! root 1: /* $Header: /src386/bin/db/RCS/i8086b.c,v 1.3 93/03/11 07:45:40 bin Exp Locker: bin $ ! 2: * ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.35 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: */ ! 15: /* ! 16: * A debugger. ! 17: * Intel 8086. ! 18: * ! 19: * $Log: i8086b.c,v $ ! 20: * Revision 1.3 93/03/11 07:45:40 bin ! 21: * Hal: post NDP update that at least ! 22: * can st breakpoints. ! 23: * ! 24: * Revision 1.1 92/06/10 14:36:31 bin ! 25: * Initial revision ! 26: * ! 27: * Revision 1.2 89/06/19 16:46:29 src ! 28: * Bug: 80286 virtual mode instructions not supported [ie: lgdt]. ! 29: * Fix: Metakey 'V' added to support 3 byte virtual mode instructions. (ABC) ! 30: * ! 31: * Revision 1.1 88/10/17 04:03:49 src ! 32: * Initial revision ! 33: * ! 34: * Revision: 386 version 92/05/01 ! 35: * Bernard Wald, Wald Software Consulting, Germany ! 36: */ ! 37: ! 38: #include <stdio.h> ! 39: #include <sys/param.h> ! 40: #include <l.out.h> ! 41: #include "trace.h" ! 42: #include "i8086.h" ! 43: ! 44: /* ! 45: * Disassemble an Intel 80386 instruction. ! 46: */ ! 47: ! 48: #define MAXINSTLEN 50 /* max. expanded opcode string length */ ! 49: #define MAXDISPLCTSIZE 6 /* max. displacement size in bytes */ ! 50: #define ESC_2_OPMAP2 0x0F /* escape to second byte of the opcode */ ! 51: ! 52: /* define instruction prefix codes */ ! 53: #define REP 0xF3 ! 54: #define REPNE 0xF2 ! 55: #define LOCK 0xF0 ! 56: ! 57: /* define address size prefix codes */ ! 58: #define ADDRPRE 0x67 ! 59: ! 60: /* define operand size prefix codes */ ! 61: #define OPDPRE 0x66 ! 62: ! 63: /* define segment override prefix codes */ ! 64: #define CS_PFX 0x2E ! 65: #define DS_PFX 0x3E ! 66: #define ES_PFX 0x26 ! 67: #define FS_PFX 0x64 ! 68: #define GS_PFX 0x65 ! 69: #define SS_PFX 0x36 ! 70: ! 71: #define EBP_SIB 5 ! 72: ! 73: #define UNSIGNED 0 ! 74: #define SIGNED 1 ! 75: ! 76: #define ADDZERO 0 ! 77: #define ADDADDR 1 ! 78: ! 79: #define mod(x) (((x)>>6)&3) ! 80: #define modR(x) (((x)>>3)&7) ! 81: #define modRM(x) ((x)&7) ! 82: #define sibss(x) (((x)>>6)&3) ! 83: #define sibx(x) (((x)>>3)&7) ! 84: #define sibb(x) ((x)&7) ! 85: ! 86: #define ADDRINDEX(x) (x == RM32 ? 1 : 0) ! 87: ! 88: #define TOLSYM 0x100 /* print symbol if greater */ ! 89: #define TOLHEX 0x10 /* print hexidecimal if greater */ ! 90: /* print decimal if less */ ! 91: static int addrflag=0; /* address size prefix flag */ ! 92: static int opdflag=0; /* operand size prefix flag */ ! 93: static int segflag=0; /* segment override prefix flag */ ! 94: static char *segPreStrp; /* segment prefix str., e.g. "cs:" */ ! 95: static unsigned char m; /* "Mod" field of ModR/M byte */ ! 96: static unsigned char mRM; /* "R/M" field of ModR/M byte */ ! 97: static unsigned char mReg; /* "REG" field of ModR/M byte */ ! 98: static unsigned char modRMloaded; /* ModR/M byte part of instruction ! 99: has already been loaded, if set */ ! 100: static unsigned char sb; /* "base" field of SIB byte */ ! 101: static unsigned char sss; /* "ss" field of SIB byte */ ! 102: static unsigned char sx; /* "index" field of SIB byte */ ! 103: static unsigned char sibLoaded; /* SIB byte part of instruction ! 104: has already been loaded, if set */ ! 105: ! 106: /* Function declatations */ ! 107: char *getmodREGstr(); ! 108: char *getmodRM16str(); ! 109: char *getmodRM32str(); ! 110: char *getsibstr(); ! 111: char *getmodRMstr(); ! 112: unsigned long getVal(); ! 113: unsigned short getValData(); ! 114: unsigned char check4prefix(); ! 115: unsigned long evalValData(); ! 116: char *getSegValStr(); ! 117: char *getASCIIimmediateStr(); ! 118: char *getASCIIdisplcmtStr(); ! 119: char *getSegPreStr(); ! 120: unsigned char c2opdsizeAdj(); ! 121: unsigned char getnbytes(); ! 122: unsigned char getgenRegIndex(); ! 123: ! 124: char * ! 125: newconinst(sp, s) ! 126: char *sp; /* pointer to assembler nmeumonic string, which will ! 127: contain the expanded string to be output (to screen). */ ! 128: int s; /* segment number */ ! 129: { ! 130: unsigned char ibp[MAXDISPLCTSIZE]; /* buffer to store read-in instruction/ ! 131: displacement machine code */ ! 132: char is[MAXINSTLEN], *isp; /* buffer to store formatted ! 133: instructon string. */ ! 134: char *tsp; /* temporary string pointer */ ! 135: int loop, useMap2; ! 136: ! 137: /* ! 138: * Initialize ! 139: */ ! 140: addrflag = 0; ! 141: opdflag = 0; ! 142: segflag = 0; ! 143: modRMloaded = 0; ! 144: sibLoaded = 0; ! 145: ! 146: isp = is; ! 147: ! 148: /* ! 149: * Check whether any prefixes are present ! 150: */ ! 151: for (loop=1, useMap2=0; loop; ) { ! 152: if (getb(s, ibp, sizeof(char)) == 0) ! 153: return (NULL); ! 154: switch (ibp[0]) { ! 155: case REP: /* rep instruction prefix */ ! 156: case REPNE: /* repne instruction prefix */ ! 157: case LOCK: /* lock instruction prefix */ ! 158: loop = 0; /* treat instruction prefixe like a */ ! 159: break; /* separate instruction */ ! 160: case ADDRPRE: /* address size prefix */ ! 161: addrflag = 1; ! 162: continue; ! 163: case OPDPRE: /* operand size prefix */ ! 164: opdflag = 1; ! 165: continue; ! 166: case CS_PFX: /* "cs:" segment override prefix */ ! 167: case DS_PFX: /* "ds:" segment override prefix */ ! 168: case ES_PFX: /* "es:" segment override prefix */ ! 169: case FS_PFX: /* "fs:" segment override prefix */ ! 170: case GS_PFX: /* "gs:" segment override prefix */ ! 171: case SS_PFX: /* "ss:" segment override prefix */ ! 172: segPreStrp = opStrMap1[ ibp[0] ]; /* store segment override */ ! 173: segflag = 1; ! 174: break; ! 175: case ESC_2_OPMAP2: /* opcode info is in the next byte */ ! 176: useMap2 = 1; ! 177: if (getb(s, ibp, sizeof(char)) == 0) ! 178: return (NULL); ! 179: loop = 0; ! 180: break; ! 181: default: ! 182: loop = 0; ! 183: } ! 184: } ! 185: ! 186: /* ! 187: * get and evaluate the formated opcode string obtained from the ! 188: * opStrMap1&2[] ! 189: */ ! 190: ! 191: /* get formatted opcode string and store in is[] */ ! 192: if ( (tsp = useMap2 ? opStrMap2[ibp[0]] : opStrMap1[ibp[0]]) == NULL ) { ! 193: sprintf(sp, "Invalid instruction byte = %02x (opStrMap%d)\n" ! 194: , ibp[0], useMap2 ? 2 : 1); ! 195: return( sp = (char *)strchr(sp, '\0') ); ! 196: } ! 197: strcpy(isp, tsp); ! 198: ! 199: /* Expand the formatted opcode string pointed at by isp to produce an ! 200: assembler nmeumonic string. Make sure sp is pointing to the current ! 201: end-of-string after each loop. */ ! 202: for ( ; isp[0]; isp++) { ! 203: switch (isp[0]) { ! 204: case '%': ! 205: if ( (isp = fmatPercent(isp, sp, s, ibp)) == NULL) { ! 206: printf("Invalid opcode string.\n"); ! 207: return(NULL); ! 208: } ! 209: /* point to end of string */ ! 210: sp = (char *)strchr(sp, '\0'); ! 211: break; ! 212: case ' ': ! 213: *sp++ = '\t'; ! 214: *sp = '\0'; ! 215: break; ! 216: default: ! 217: *sp++ = isp[0]; ! 218: *sp = '\0'; ! 219: ! 220: } ! 221: } ! 222: return(sp); ! 223: } ! 224: ! 225: ! 226: /* ! 227: * Evalute "%c1c2" and store the expanded results in wb[]. Then, copy wb[] into ! 228: * sp[] and return isp pointing to the next character of the formatted ! 229: * instruction string. ! 230: * ! 231: * CAREFULL! - when doing string manipulations, make sure that wbp ! 232: * is pointing at '\0' before breaking from switch statement. ! 233: */ ! 234: char * ! 235: fmatPercent(isp, sp, s, ibp) ! 236: char *isp, *sp; ! 237: int s; ! 238: unsigned char *ibp; ! 239: { ! 240: char wb[MAXINSTLEN], *wbp; /* work buffer (pointer) */ ! 241: unsigned char c1, c2; /* 1st & 2nd char after '%' */ ! 242: long deltaVal; ! 243: unsigned long val; ! 244: char *tsp1, *tsp2; /* temporary string pointer */ ! 245: ! 246: c1 = *++isp; ! 247: c2 = *++isp; ! 248: wbp = wb; ! 249: wbp[0] = '\0'; ! 250: ! 251: switch (c1) { ! 252: case 'A': ! 253: c2 = c2opdsizeAdj(c2); ! 254: val = getVal(s, ibp, c2, UNSIGNED, ADDZERO, &deltaVal); ! 255: wbp = getSegValStr(ibp, wbp, c2); ! 256: wbp = getASCIIdisplcmtStr(wbp, 'a', UNSIGNED, s, deltaVal, val); ! 257: break; ! 258: case 'C': ! 259: getmodRM(s, ibp, sizeof(char)); ! 260: wbp = (char *)strcpy(wbp, ctrlReg[mReg]); ! 261: wbp = (char *)strchr(wbp, '\0'); ! 262: break; ! 263: case 'D': ! 264: getmodRM(s, ibp, sizeof(char)); ! 265: wbp = (char *)strcpy(wbp, dbgReg[mReg]); ! 266: wbp = (char *)strchr(wbp, '\0'); ! 267: break; ! 268: case 'E': ! 269: case 'M': ! 270: case 'R': ! 271: if (getaddrsize() == RM16) ! 272: wbp = getmodRM16str(s, ibp, c2, wbp); ! 273: else ! 274: wbp = getmodRM32str(s, ibp, c2, wbp); ! 275: break; ! 276: case 'G': ! 277: wbp = getmodREGstr(s, ibp, c2, wbp); ! 278: break; ! 279: case 'I': ! 280: *wbp++ = '$'; ! 281: c2 = c2opdsizeAdj(c2); ! 282: val = getVal(s, ibp, c2, SIGNED, ADDZERO, &deltaVal); ! 283: wbp = getSegValStr(ibp, wbp, c2); ! 284: wbp = getASCIIimmediateStr(wbp, 'x', ! 285: SIGNED, s, deltaVal, val, c2); ! 286: break; ! 287: case 'J': ! 288: wbp = getSegPreStr(wbp); ! 289: c2 = c2opdsizeAdj(c2); ! 290: val = getVal(s, ibp, c2, SIGNED, ADDADDR, &deltaVal); ! 291: wbp = getSegValStr(ibp, wbp, c2); ! 292: wbp = getASCIIdisplcmtStr(wbp, 'a', SIGNED, s, deltaVal, val); ! 293: break; ! 294: case 'K': ! 295: wbp = getSegPreStr(wbp); ! 296: c2 = c2opdsizeAdj(c2); ! 297: val = getVal(s, ibp, c2, SIGNED, ADDADDR, &deltaVal); ! 298: wbp = getSegValStr(ibp, wbp, c2); ! 299: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED, s, deltaVal, val); ! 300: break; ! 301: /* case 'M': see case 'E' ! 302: break; */ ! 303: case 'O': ! 304: wbp = getSegPreStr(wbp); ! 305: c2 = getaddrsize() == RM16 ? 'w' : 'd'; ! 306: val = getVal(s, ibp, c2, SIGNED, ADDZERO, &deltaVal); ! 307: wbp = getSegValStr(ibp, wbp, c2); ! 308: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED, ! 309: (hdrinfo.defsegatt == RM16 ? 2 : 1), deltaVal, val); ! 310: break; ! 311: /* case 'R': see case 'E' ! 312: break; */ ! 313: case 'S': ! 314: getmodRM(s, ibp, sizeof(char)); ! 315: wbp = (char *)strcpy(wbp, segReg[mReg]); ! 316: wbp = (char *)strchr(wbp, '\0'); ! 317: break; ! 318: case 'T': ! 319: getmodRM(s, ibp, sizeof(char)); ! 320: wbp = (char *)strcpy(wbp, tstReg[mReg]); ! 321: wbp = (char *)strchr(wbp, '\0'); ! 322: break; ! 323: case 'X': ! 324: /* if (getaddrsize()==RM16) { ! 325: sprintf(wbp, "ds:(%%si)"); ! 326: } ! 327: else { ! 328: sprintf(wbp, "ds:(%%esi)"); ! 329: } ! 330: wbp = (char *)strchr(wbp, '\0'); ! 331: break; ! 332: */ case 'Y': ! 333: /* if (getaddrsize()==RM16) { ! 334: sprintf(wbp, "es:(%%di)"); ! 335: } ! 336: else { ! 337: sprintf(wbp, "es:(%%edi)"); ! 338: } ! 339: wbp = (char *)strchr(wbp, '\0'); ! 340: */ break; ! 341: case 'Z': ! 342: c2 = c2opdsizeAdj(c2); ! 343: switch(c2) { ! 344: case 'b': ! 345: *wbp++ = 'b'; ! 346: break; ! 347: case 'd': ! 348: *wbp++ = 'l'; ! 349: break; ! 350: case 'w': ! 351: *wbp++ = 'w'; ! 352: break; ! 353: case 'z': ! 354: *wbp++ = (getopdsize()==RM16 ? 'w': 'l'); ! 355: break; ! 356: } ! 357: wbp[0] = '\0'; ! 358: break; ! 359: case 'e': ! 360: if (getopdsize()==OPD16) { ! 361: *wbp++ = '%'; ! 362: *wbp++ = c2; ! 363: *wbp = '\0'; ! 364: } ! 365: else { ! 366: *wbp++ = '%'; ! 367: *wbp++ = 'e'; ! 368: *wbp++ = c2; ! 369: *wbp = '\0'; ! 370: } ! 371: break; ! 372: case 'g': /* just inserting the group string into isp */ ! 373: getmodRM(s, ibp, sizeof(char)); ! 374: if (grpStrMap[c2-'0'][mReg] == NULL) { ! 375: sprintf(wbp, "\nInvalid instruction byte = %02x (grpStrMap[%d][%d])\n" ! 376: , ibp[0], c2-'0', mReg); ! 377: return( wbp = (char *)strchr(wbp, '\0') ); ! 378: } ! 379: tsp1 = malloc(MAXINSTLEN); ! 380: tsp2 = isp; ! 381: strcpy(tsp1, isp+1); ! 382: strcpy(isp+1, grpStrMap[c2-'0'][mReg]); ! 383: isp = (char *)strchr(isp+1, '\0'); ! 384: strcpy(isp, tsp1); ! 385: isp = tsp2; ! 386: free(tsp1); ! 387: *wbp = '\0'; ! 388: break; ! 389: case 'r': ! 390: if (getb(s, ibp, sizeof(char)) == 0) ! 391: return (NULL); ! 392: break; ! 393: default: ! 394: *wbp++ = c1; ! 395: *wbp++ = c2; ! 396: *wbp = '\0'; ! 397: } ! 398: ! 399: sp = (char *)strcpy(sp, wb); ! 400: ! 401: return(isp); ! 402: } ! 403: ! 404: char * ! 405: getmodREGstr(s, ibp, c2, wbp) ! 406: int s; ! 407: unsigned char *ibp; ! 408: char c2, *wbp; ! 409: { ! 410: getmodRM(s, ibp, sizeof(char)); ! 411: strcpy(wbp, genReg[getgenRegIndex(c2)][mReg]); ! 412: wbp = (char *)strchr(wbp, '\0'); ! 413: return(wbp); ! 414: } ! 415: ! 416: char * ! 417: getmodRM16str(s, ibp, c2, wbp) ! 418: int s; ! 419: unsigned char *ibp; ! 420: char c2, *wbp; ! 421: { ! 422: unsigned char genRegIndex; ! 423: long deltaVal; ! 424: unsigned long val; ! 425: ! 426: getmodRM(s, ibp, sizeof(char)); ! 427: c2 = c2opdsizeAdj(c2); ! 428: ! 429: switch(m) { ! 430: case 0: ! 431: if (mRM==6) { ! 432: wbp = getSegPreStr(wbp); ! 433: val = getVal(s, ibp, 'w', SIGNED, ADDZERO, &deltaVal); ! 434: wbp = getSegValStr(ibp, wbp, 'w'); ! 435: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED, ! 436: (hdrinfo.defsegatt == RM16 ? 2 : 1), deltaVal, val); ! 437: break; ! 438: } ! 439: wbp = getSegPreStr(wbp); ! 440: wbp = (char *)strcpy(wbp, modRMtab16[mRM] ); ! 441: wbp = (char *)strchr(wbp, '\0'); ! 442: break; ! 443: case 1: ! 444: wbp = getmodRMstr(s, ibp, wbp, 'b', 'd', RM16, 1); ! 445: break; ! 446: case 2: ! 447: wbp = getmodRMstr(s, ibp, wbp, 'w', 'd', RM16, 1); ! 448: break; ! 449: case 3: ! 450: genRegIndex = getgenRegIndex(c2); ! 451: ! 452: wbp = (char *)strcpy(wbp, genReg[genRegIndex][mRM]); ! 453: wbp = (char *)strchr(wbp, '\0'); ! 454: break; ! 455: } ! 456: return(wbp); ! 457: } ! 458: ! 459: char * ! 460: getmodRM32str(s, ibp, c2, wbp) ! 461: int s; ! 462: unsigned char *ibp; ! 463: char c2, *wbp; ! 464: { ! 465: unsigned char genRegIndex; ! 466: long deltaVal; ! 467: unsigned long val; ! 468: ! 469: getmodRM(s, ibp, sizeof(char)); ! 470: c2 = c2opdsizeAdj(c2); ! 471: ! 472: switch(m) { ! 473: case 0: ! 474: if (mRM==4) { ! 475: wbp = getsibstr(s, ibp, wbp, '\0', m); ! 476: break; ! 477: } ! 478: if (mRM==5) { ! 479: wbp = getSegPreStr(wbp); ! 480: val = getVal(s, ibp, 'd', SIGNED, ADDZERO, &deltaVal); ! 481: wbp = getSegValStr(ibp, wbp, 'd'); ! 482: wbp = getASCIIdisplcmtStr(wbp, 's', SIGNED, ! 483: (hdrinfo.defsegatt == RM16 ? 2 : 1), deltaVal, val); ! 484: break; ! 485: } ! 486: wbp = getSegPreStr(wbp); ! 487: wbp = (char *)strcpy(wbp, modRMtab32[mRM] ); ! 488: wbp = (char *)strchr(wbp, '\0'); ! 489: break; ! 490: case 1: ! 491: if (mRM==4) { ! 492: wbp = getsibstr(s, ibp, wbp, 'b', m); ! 493: break; ! 494: } ! 495: wbp = getmodRMstr(s, ibp, wbp, 'b', 'd', RM32, 1); ! 496: break; ! 497: case 2: ! 498: if (mRM==4) { ! 499: wbp = getsibstr(s, ibp, wbp, 'd', m); ! 500: break; ! 501: } ! 502: wbp = getmodRMstr(s, ibp, wbp, 'd', 'd', RM32, 1); ! 503: break; ! 504: case 3: ! 505: genRegIndex = getgenRegIndex(c2); ! 506: ! 507: wbp = (char *)strcpy(wbp, genReg[genRegIndex][mRM]); ! 508: wbp = (char *)strchr(wbp, '\0'); ! 509: break; ! 510: } ! 511: return(wbp); ! 512: } ! 513: ! 514: char * ! 515: getmodRMstr(s, ibp, wbp, displctsize, form, addrsize, signedVal) ! 516: int s; ! 517: unsigned char *ibp; ! 518: char *wbp; ! 519: unsigned char displctsize, form, addrsize, signedVal; ! 520: { ! 521: long deltaVal; ! 522: unsigned long val; ! 523: ! 524: wbp = getSegPreStr(wbp); ! 525: ! 526: val = getVal(s, ibp, displctsize, signedVal, ADDZERO, &deltaVal); ! 527: wbp = getSegValStr(ibp, wbp, displctsize); ! 528: wbp = getASCIIdisplcmtStr(wbp, form, signedVal, s, deltaVal, val); ! 529: ! 530: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(addrsize)][mRM] ); ! 531: wbp = (char *)strchr(wbp, '\0'); ! 532: ! 533: return(wbp); ! 534: } ! 535: ! 536: char * ! 537: getsibstr(s, ibp, wbp, displctsize, m) ! 538: int s; ! 539: unsigned char *ibp; ! 540: char *wbp; ! 541: unsigned char displctsize, m; ! 542: { ! 543: long deltaVal; ! 544: unsigned long val; ! 545: ! 546: getsib(s, ibp, sizeof(char)); ! 547: ! 548: switch(m) { ! 549: case 0: ! 550: wbp = getSegPreStr(wbp); ! 551: if (sb == EBP_SIB) { ! 552: val = getVal(s, ibp, 'd', SIGNED, ADDZERO, &deltaVal); ! 553: wbp = getSegValStr(ibp, wbp, 'd'); ! 554: wbp = getASCIIdisplcmtStr(wbp, 'd', SIGNED, s, deltaVal, val); ! 555: } ! 556: else { ! 557: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(RM32)][sb]); ! 558: wbp = (char *)strchr(wbp, '\0'); ! 559: } ! 560: break; ! 561: case 1: ! 562: wbp = getSegPreStr(wbp); ! 563: ! 564: val = getVal(s, ibp, displctsize, SIGNED, ADDZERO, &deltaVal); ! 565: wbp = getSegValStr(ibp, wbp, displctsize); ! 566: wbp = getASCIIdisplcmtStr(wbp, 'd', SIGNED, s, deltaVal, val); ! 567: ! 568: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(RM32)][sb]); ! 569: wbp = (char *)strchr(wbp, '\0'); ! 570: break; ! 571: case 2: ! 572: wbp = getSegPreStr(wbp); ! 573: ! 574: val = getVal(s, ibp, displctsize, SIGNED, ADDZERO, &deltaVal); ! 575: wbp = getSegValStr(ibp, wbp, displctsize); ! 576: wbp = getASCIIdisplcmtStr(wbp, 'd', SIGNED, s, deltaVal, val); ! 577: ! 578: wbp = (char *)strcpy(wbp, modRMtab[ADDRINDEX(RM32)][sb]); ! 579: wbp = (char *)strchr(wbp, '\0'); ! 580: break; ! 581: } ! 582: if (sibtab[sss][sx] != NULL) { ! 583: wbp = (char *)strcpy(wbp, sibtab[sss][sx]); ! 584: wbp = (char *)strchr(wbp, '\0'); ! 585: } ! 586: return(wbp); ! 587: } ! 588: ! 589: unsigned long ! 590: getVal(s, ibp, mysizeof, signedVal, addVal, deltaValp) ! 591: int s; ! 592: unsigned char *ibp; ! 593: unsigned char mysizeof, signedVal; ! 594: unsigned char addVal; ! 595: long *deltaValp; ! 596: { ! 597: unsigned char nbytes; ! 598: unsigned long val; ! 599: ! 600: if ( (nbytes = getValData(s, ibp, signedVal, mysizeof)) == 0) ! 601: return(ADDZERO); ! 602: nbytes = check4prefix(mysizeof, nbytes); ! 603: val = evalValData(ibp, signedVal, nbytes, addVal, deltaValp); ! 604: return(val); ! 605: } ! 606: ! 607: unsigned short ! 608: getValData(s, ibp, signedVal, mysizeof) ! 609: int s; ! 610: unsigned char *ibp, signedVal; ! 611: unsigned char mysizeof; ! 612: { ! 613: unsigned char nbytes, i; ! 614: ! 615: if ( (nbytes = getnbytes(mysizeof)) == 0 ) ! 616: return(0); ! 617: ! 618: if ( (getb(s, ibp, nbytes)) == 0 ) { ! 619: printf("Unable to read opcode displacement or immediate data\n"); ! 620: return (0); ! 621: } ! 622: ! 623: for (i=nbytes; i<MAXDISPLCTSIZE; i++) { ! 624: if (signedVal) ! 625: ibp[i] = (ibp[i-1] & 0x80) ? 0xFF : 0; ! 626: else ! 627: ibp[i] = 0; ! 628: } ! 629: return(nbytes); ! 630: } ! 631: ! 632: unsigned char ! 633: check4prefix(mysizeof, nbytes) ! 634: { ! 635: switch(mysizeof) { ! 636: case 'f': /* 32 bit pointer */ ! 637: case 'l': /* 48 bit pointer */ ! 638: nbytes -= 2; ! 639: break; ! 640: } ! 641: return(nbytes); ! 642: } ! 643: ! 644: unsigned long ! 645: evalValData(ibp, signedVal, nbytes, addVal, deltaValp) ! 646: unsigned char *ibp; ! 647: unsigned char signedVal, nbytes; ! 648: unsigned char addVal; ! 649: long *deltaValp; ! 650: { ! 651: unsigned long baseVal, val; ! 652: ! 653: if (addVal) ! 654: baseVal = add; ! 655: else baseVal = 0L; ! 656: ! 657: switch (nbytes) { ! 658: case DBBYTE: ! 659: if (signedVal) { ! 660: *deltaValp = *(signed char *)ibp; ! 661: if ((signed long)*deltaValp >= 0) ! 662: val = baseVal + *deltaValp; ! 663: else ! 664: val = baseVal ! 665: - (unsigned long) ! 666: (-(signed long)*deltaValp); ! 667: } ! 668: else { ! 669: *deltaValp = *(unsigned char *)ibp; ! 670: val = baseVal + *deltaValp; ! 671: } ! 672: break; ! 673: case DBWORD: ! 674: if (signedVal) { ! 675: *deltaValp = *(signed short *)ibp; ! 676: if ((signed long)*deltaValp >= 0) ! 677: val = baseVal + *deltaValp; ! 678: else ! 679: val = baseVal ! 680: - (unsigned long) ! 681: (-(signed long)*deltaValp); ! 682: } ! 683: else { ! 684: *deltaValp = *(unsigned short *)ibp; ! 685: val = baseVal + *deltaValp; ! 686: } ! 687: break; ! 688: case DBLONG: ! 689: *deltaValp = *(long *)ibp; ! 690: if (signedVal) { ! 691: if ((signed long)*deltaValp >= 0) ! 692: val = baseVal + *deltaValp; ! 693: else ! 694: val = baseVal ! 695: - (unsigned long) ! 696: (-(signed long)*deltaValp); ! 697: } ! 698: else { ! 699: val = baseVal + *deltaValp; ! 700: } ! 701: break; ! 702: } ! 703: return(val); ! 704: } ! 705: ! 706: char * ! 707: getSegValStr(ibp, wbp, mysizeof) ! 708: unsigned char *ibp; ! 709: char *wbp; ! 710: unsigned char mysizeof; ! 711: { ! 712: unsigned char nbytes; ! 713: ! 714: nbytes = getnbytes(mysizeof); ! 715: ! 716: switch(mysizeof) { ! 717: case 'f': /* 32 bit pointer */ ! 718: case 'l': /* 48 bit pointer */ ! 719: sprintf(wbp, "0x%02x%02x:", ibp[nbytes-1], ibp[nbytes-2]); ! 720: wbp = (char *)strchr(wbp, '\0'); ! 721: break; ! 722: } ! 723: return(wbp); ! 724: } ! 725: ! 726: char * ! 727: getASCIIimmediateStr(wbp, form, signedVal, segn, deltaVal, val, mysizeof) ! 728: char *wbp; ! 729: unsigned char form, signedVal; ! 730: int segn; ! 731: signed long deltaVal; ! 732: unsigned long val; ! 733: unsigned char mysizeof; ! 734: { ! 735: switch (getnbytes(mysizeof)) { ! 736: case DBBYTE: ! 737: val &= 0xFF; ! 738: break; ! 739: case DBWORD: ! 740: val &= 0xFFFF; ! 741: break; ! 742: } ! 743: getASCIIdisplcmtStr(wbp, form, signedVal, segn, deltaVal, val); ! 744: } ! 745: ! 746: char * ! 747: getASCIIdisplcmtStr(wbp, form, signedVal, segn, deltaVal, val) ! 748: char *wbp; ! 749: unsigned char form, signedVal; ! 750: int segn; ! 751: signed long deltaVal; ! 752: unsigned long val; ! 753: { ! 754: if (signedVal && deltaVal<0) ! 755: deltaVal = -deltaVal; ! 756: switch(form) { ! 757: case 'a': /* print address */ ! 758: if ( deltaVal > TOLSYM) /* print out symbol, if possible */ ! 759: conaddr(wbp, segn, val, I); ! 760: else { /* Print out address in hex format */ ! 761: *wbp = '('; ! 762: printaddr(wbp, val); ! 763: wbp = (char *)strchr(wbp, '\0'); ! 764: *wbp = ')'; ! 765: *wbp = '\0'; ! 766: } ! 767: break; ! 768: case 'd': /* print decimal */ ! 769: if (!val) ! 770: break; ! 771: /* if (deltaVal > TOLSYM) { ! 772: conaddr(wbp, segn, val, I); ! 773: } ! 774: else { ! 775: */ if (getopdsize()==OPD16) { ! 776: sprintf(wbp, "%d", val); ! 777: } ! 778: else { ! 779: sprintf(wbp, "%ld", val); ! 780: } ! 781: /* } ! 782: */ break; ! 783: case 's': /* if available, print symbol; otherwise print address */ ! 784: conaddr(wbp, segn, val, I); ! 785: break; ! 786: case 'x': /* print hex */ ! 787: /* if (deltaVal > TOLSYM) { ! 788: conaddr(wbp, segn, val, I); ! 789: } ! 790: else { ! 791: */ if (getopdsize()==OPD16) { ! 792: if (deltaVal > TOLHEX) { ! 793: sprintf(wbp, "0x%x", val); ! 794: } ! 795: else { ! 796: sprintf(wbp, "%d", val); ! 797: } ! 798: } ! 799: else { ! 800: if (deltaVal > TOLHEX) { ! 801: sprintf(wbp, "0x%lx", val); ! 802: } ! 803: else { ! 804: sprintf(wbp, "%ld", val); ! 805: } ! 806: } ! 807: /* } ! 808: */ break; ! 809: default: ! 810: if(1) printf("invalid form = %c; ", form); ! 811: } ! 812: ! 813: wbp = (char *)strchr(wbp, '\0'); ! 814: return(wbp); ! 815: } ! 816: ! 817: printaddr(wbp, v) ! 818: char *wbp; ! 819: unsigned long v; ! 820: { ! 821: if (getopdsize()==OPD16) { ! 822: sprintf(wbp, "%04x", v); ! 823: } ! 824: else { ! 825: sprintf(wbp, "%04X", v); ! 826: } ! 827: } ! 828: ! 829: char * ! 830: getSegPreStr(wbp) ! 831: char *wbp; ! 832: { ! 833: if (segflag) { ! 834: strcpy(wbp, segPreStrp); ! 835: wbp = (char *)strchr(wbp, '\0'); ! 836: } ! 837: return(wbp); ! 838: } ! 839: ! 840: unsigned char c2opdsizeAdj(c2) ! 841: unsigned char c2; ! 842: { ! 843: if (getopdsize()==RM16) { ! 844: switch(c2) { /* set to addr16 lengths */ ! 845: case 'a': ! 846: c2 = 'w'; ! 847: break; ! 848: case 'p': ! 849: c2 = 'f'; ! 850: break; ! 851: case 'v': ! 852: c2 = 'w'; ! 853: break; ! 854: } ! 855: } ! 856: else { ! 857: switch(c2) { /* set to addr32 lengths */ ! 858: case 'a': ! 859: c2 = 'd'; ! 860: break; ! 861: case 'p': ! 862: c2 = 'l'; ! 863: break; ! 864: case 'v': ! 865: c2 = 'd'; ! 866: break; ! 867: } ! 868: } ! 869: return(c2); ! 870: } ! 871: ! 872: unsigned char ! 873: getnbytes(mysizeof) ! 874: unsigned char mysizeof; ! 875: { ! 876: unsigned char nbytes; ! 877: ! 878: switch(mysizeof) { ! 879: case 'b': ! 880: nbytes = DBBYTE; ! 881: break; ! 882: case 'd': ! 883: nbytes = DBLONG; ! 884: break; ! 885: case 'f': ! 886: nbytes = DBPTR32; ! 887: break; ! 888: case 'l': ! 889: nbytes = DBPTR48; ! 890: break; ! 891: case 'w': ! 892: nbytes = DBWORD; ! 893: break; ! 894: case '\0': ! 895: nbytes = 0; ! 896: break; ! 897: default: ! 898: if(1) printf("invalid nbytes = %c; " ! 899: "a 1 byte size is chosen by default\n" ! 900: , mysizeof); ! 901: nbytes = DBBYTE; ! 902: } ! 903: return(nbytes); ! 904: } ! 905: ! 906: unsigned char ! 907: getgenRegIndex(c2) ! 908: unsigned char c2; ! 909: { ! 910: unsigned char genRegIndex; ! 911: ! 912: switch(c2) { ! 913: case 'a': ! 914: if (getopdsize() == OPD16) ! 915: genRegIndex = 1; ! 916: else ! 917: genRegIndex = 2; ! 918: break; ! 919: case 'b': ! 920: genRegIndex = 0; ! 921: break; ! 922: case 'd': ! 923: genRegIndex = 2; ! 924: break; ! 925: case 'v': ! 926: if (getopdsize() == OPD16) ! 927: genRegIndex = 1; ! 928: else ! 929: genRegIndex = 2; ! 930: break; ! 931: case 'w': ! 932: genRegIndex = 1; ! 933: break; ! 934: default: ! 935: if(1) printf("invalid c2 = %c; " ! 936: "a 1 byte reg is shown by default\n" ! 937: , c2); ! 938: genRegIndex = 0; ! 939: } ! 940: return(genRegIndex); ! 941: } ! 942: ! 943: getaddrsize() ! 944: { ! 945: return( addrflag ? 48 - hdrinfo.defsegatt : hdrinfo.defsegatt ); ! 946: } ! 947: ! 948: getopdsize() ! 949: { ! 950: return( opdflag ? 48 - hdrinfo.defsegatt : hdrinfo.defsegatt ); ! 951: } ! 952: ! 953: getmodRM(s, ibp, c) ! 954: unsigned char *ibp; ! 955: unsigned c; ! 956: { ! 957: if (!modRMloaded) { ! 958: if (getb(s, ibp, c) == 0) ! 959: return (NULL); ! 960: m = mod(ibp[0]); ! 961: mRM = modRM(ibp[0]); ! 962: mReg = modR(ibp[0]); ! 963: modRMloaded = 1; ! 964: } ! 965: } ! 966: ! 967: getsib(s, ibp, c) ! 968: unsigned char *ibp; ! 969: unsigned c; ! 970: { ! 971: if (!sibLoaded) { ! 972: if ((getb(s, ibp, c)) == 0) ! 973: return (NULL); ! 974: sss = sibss(ibp[0]); ! 975: sx = sibx(ibp[0]); ! 976: sb = sibb(ibp[0]); ! 977: sibLoaded = 1; ! 978: } ! 979: } ! 980: ! 981: /* ! 982: * Given a size character, `t1', and a type, `t2', return the appropriate ! 983: * format string. ! 984: */ ! 985: char * ! 986: getform(t1, t2) ! 987: register int t1; ! 988: register int t2; ! 989: { ! 990: register char *cp; ! 991: register char *sp; ! 992: ! 993: if (t1=='f' || t1=='F') ! 994: return ("%g"); ! 995: if (t1 == 'h') ! 996: t1 = 'w'; ! 997: if ((cp=strchr(sp="bwlv", t1)) == NULL) ! 998: return ("?"); ! 999: t1 = cp-sp; ! 1000: if ((cp=strchr(sp="duox", t2)) == NULL) ! 1001: return ("?"); ! 1002: t2 = cp-sp; ! 1003: return (formtab[t1][t2]); ! 1004: } ! 1005: ! 1006: /* End of i8086b1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.