|
|
1.1 ! root 1: /* ! 2: * A debugger. ! 3: * Intel 8086. ! 4: */ ! 5: #include <stdio.h> ! 6: #include <sys/const.h> ! 7: #include "trace.h" ! 8: #include "i8086.h" ! 9: ! 10: /* ! 11: * Disassemble an Intel 8086 instruction. ! 12: */ ! 13: char * ! 14: coninst(sp, s) ! 15: register char *sp; ! 16: { ! 17: register INS *ip; ! 18: register char *cp; ! 19: register int r; ! 20: register long a; ! 21: unsigned char b[1]; ! 22: ! 23: r = -1; ! 24: for (;;) { ! 25: if (getb(s, b, sizeof(b)) == 0) ! 26: return (NULL); ! 27: if ((b[0]&0xE7) == 0x26) { /* Segment override */ ! 28: r = (b[0]>>3)&0x3; ! 29: continue; ! 30: } ! 31: a = add; ! 32: for (ip=insrtab; ip->i_name!=NULL; ip++) { ! 33: if ((b[0]&ip->i_mask) != ip->i_code) ! 34: continue; ! 35: add = a; ! 36: if ((cp=putifmt(sp, s, ip->i_name, b[0], r, 1))!=NULL) ! 37: return (cp); ! 38: } ! 39: break; ! 40: } ! 41: sprintf(sp, ".byte\t0x%02x", b[0]); ! 42: return (&sp[8]); ! 43: } ! 44: ! 45: /* ! 46: * Print out the operands to a Intel 8086 instruction according to a ! 47: * format string. ! 48: */ ! 49: char * ! 50: putifmt(sp, s, fp, ins0, segm, t) ! 51: register char *sp; ! 52: register char *fp; ! 53: unsigned ins0; ! 54: { ! 55: register char *cp; ! 56: register int c; ! 57: register int e; ! 58: register int m; ! 59: register int n; ! 60: unsigned insn; ! 61: int insk; ! 62: char x[1]; ! 63: unsigned char b[1]; ! 64: register INS *ip; ! 65: ! 66: e = 0; ! 67: m = 0; ! 68: n = 0; ! 69: insn = ins0; ! 70: while ((c=*fp++) != '\0') { ! 71: if (c != '%') { ! 72: *sp++ = c; ! 73: continue; ! 74: } ! 75: next: ! 76: switch (c=*fp++) { ! 77: case '0': ! 78: case '1': ! 79: case '2': ! 80: case '3': ! 81: case '4': ! 82: case '5': ! 83: case '6': ! 84: case '7': ! 85: n = c - '0'; ! 86: m = 1 << n; ! 87: goto next; ! 88: case ':': ! 89: if (segm >= 0) { ! 90: *sp++ = "ecsd"[segm]; ! 91: *sp++ = 's'; ! 92: *sp++ = ':'; ! 93: } ! 94: goto next; ! 95: /* ! 96: case 'a': ! 97: v = (i>=-0x100 && i<=0x100) ? -1 : I; ! 98: sp = conaddr(sp, 0, (long)(unsigned)i, v); ! 99: */ ! 100: case 'b': ! 101: if (getb(s, x, sizeof(x)) == 0) ! 102: return (NULL); ! 103: insk = x[0]; ! 104: goto next; ! 105: case 'd': ! 106: cp = (insn&m) ? "%n3r,%m" : "%nm,%3r"; ! 107: sp = putifmt(sp, s, cp, ins0, segm, t); ! 108: continue; ! 109: case 'e': ! 110: e = insn&m; ! 111: goto next; ! 112: case 'f': ! 113: if (((insn>>3)&0x7) != *fp++-'0') ! 114: return (NULL); ! 115: goto next; ! 116: case 'g': ! 117: if (insn != 10) ! 118: sprintf(sp, "\t$0x%04x", insn); ! 119: continue; ! 120: case 'h': /* 8087 escape */ ! 121: insk = ((ins0&0x7)<<3) | ((insn>>3)&0x7); ! 122: sprintf(sp, "%x", insk); ! 123: goto skip; ! 124: case 'i': ! 125: if (e==0 && t!=0) { ! 126: if (getb(s, &insk, sizeof(insk)) == 0) ! 127: return (NULL); ! 128: } else { ! 129: if (getb(s, b, sizeof(b)) == 0) ! 130: return (NULL); ! 131: if (e == 0) ! 132: insk = b[0]; ! 133: else ! 134: insk = x[0] = b[0]; ! 135: } ! 136: goto next; ! 137: case 'j': ! 138: cp = jumptab[ins0&0xF]; ! 139: goto copy; ! 140: case 'k': ! 141: sp = conaddr(sp, 2, (long)(unsigned)insk, ! 142: (unsigned)insk>0x100 ? 16 : -1); ! 143: goto skip; ! 144: case 'l': ! 145: sprintf(sp, "0x%04x", insk); ! 146: goto skip; ! 147: case 'm': ! 148: if ((insk=(insn>>6)&0x03) == 3) { ! 149: n = 0; ! 150: goto regn; ! 151: } ! 152: if (segm >= 0) { ! 153: *sp++ = "ecsd"[segm]; ! 154: *sp++ = 's'; ! 155: *sp++ = ':'; ! 156: } ! 157: switch (insk) { ! 158: case 0: ! 159: if ((insn&0x7) == 0x6) { ! 160: sp = putifmt(sp, s, "%wp", ins0, ! 161: segm, t); ! 162: continue; ! 163: } ! 164: insk = 0; ! 165: break; ! 166: case 1: ! 167: if (getb(s, x, sizeof(x)) == 0) ! 168: return (NULL); ! 169: insk = x[0]; ! 170: break; ! 171: case 2: ! 172: if (getb(s, &insk, sizeof(insk)) == 0) ! 173: return (NULL); ! 174: break; ! 175: case 3: ! 176: n = 0; ! 177: goto regn; ! 178: } ! 179: if (insk != 0) { ! 180: if (insk>=-0x100 && insk<=0x100) { ! 181: sprintf(sp, "%d", insk); ! 182: while (*sp) ! 183: sp++; ! 184: } else { ! 185: sp = conaddr(sp, 0, ! 186: (long)(unsigned)insk, I); ! 187: } ! 188: } ! 189: cp = indmtab[insn&0x7]; ! 190: goto copy; ! 191: case 'n': ! 192: if (getb(s, b, sizeof(b)) == 0) ! 193: return (NULL); ! 194: insn = b[0]; ! 195: goto next; ! 196: case 'o': ! 197: insk += add; ! 198: goto next; ! 199: case 'p': ! 200: sp = conaddr(sp, segm==1?1:0, (long)(unsigned)insk, I); ! 201: continue; ! 202: case 'q': ! 203: sp = conaddr(sp, 1, (long)(unsigned)insk, I); ! 204: continue; ! 205: case 'r': ! 206: regn: ! 207: cp = (t?regwtab:regbtab)[(insn>>n)&07]; ! 208: *sp++ = *cp++; ! 209: *sp++ = *cp++; ! 210: continue; ! 211: case 's': ! 212: *sp++ = "ecsd"[(insn>>n)&03]; ! 213: *sp++ = 's'; ! 214: continue; ! 215: case 't': ! 216: if ((t=insn&m) == 0) ! 217: *sp++ = 'b'; ! 218: continue; ! 219: case 'u': ! 220: if (getb(s, b, sizeof(b)) == 0) ! 221: return (NULL); ! 222: insk = b[0]; ! 223: goto next; ! 224: case 'v': ! 225: if ((ins0&m) == 0) { ! 226: *sp++ = '$'; ! 227: *sp++ = '1'; ! 228: } else { ! 229: *sp++ = 'c'; ! 230: *sp++ = 'l'; ! 231: } ! 232: continue; ! 233: case 'w': ! 234: if (getb(s, &insk, sizeof(insk)) == 0) ! 235: return (NULL); ! 236: goto next; ! 237: case 'x': ! 238: *sp++ = 'a'; ! 239: *sp++ = t ? 'x' : 'l'; ! 240: continue; ! 241: case 'y': ! 242: if ((insk&0x80) != 0 ! 243: && (n=insk&0x7F) < NMICALL ! 244: && (cp=sysitab[n]) != NULL) ! 245: sprintf(sp, "sys\t%s", cp); ! 246: else ! 247: sprintf(sp, "int\t0x%x", insk); ! 248: goto skip; ! 249: case 'z': ! 250: if ((insn&m) != 0) ! 251: return (NULL); ! 252: goto next; ! 253: ! 254: case 'F': /* 8087 codes */ ! 255: if (getb(s, b, sizeof(b)) == 0) ! 256: return (NULL); ! 257: insk = ((insn&0x7)<<8) | b[0]; ! 258: insn = b[0]; ! 259: for (ip = fpinstab; ip->i_name!=NULL; ip++) { ! 260: if ((insk&ip->i_mask) != ip->i_code) ! 261: continue; ! 262: sp = putifmt(sp, s, ip->i_name, b[0], segm, t); ! 263: goto skip; ! 264: } ! 265: return (NULL); ! 266: ! 267: case 'P': /* Long pointers */ ! 268: if (getb(s, &insn, sizeof (insn)) == 0) ! 269: return (NULL); ! 270: sprintf(sp, "0x%04x:0x%04x", insn, insk); ! 271: goto skip; ! 272: } ! 273: copy: ! 274: while (*cp) ! 275: *sp++ = *cp++; ! 276: continue; ! 277: skip: ! 278: while (*sp) ! 279: sp++; ! 280: continue; ! 281: } ! 282: return (sp); ! 283: } ! 284: ! 285: /* ! 286: * Given a size character, `t1', and a type, `t2', return the appropriate ! 287: * format string. ! 288: */ ! 289: char * ! 290: getform(t1, t2) ! 291: register int t1; ! 292: register int t2; ! 293: { ! 294: register char *cp; ! 295: register char *sp; ! 296: ! 297: if (t1=='f' || t1=='F') ! 298: return ("%g"); ! 299: if (t1 == 'h') ! 300: t1 = 'w'; ! 301: if ((cp=index(sp="bwlv", t1)) == NULL) ! 302: return ("?"); ! 303: t1 = cp-sp; ! 304: if ((cp=index(sp="duox", t2)) == NULL) ! 305: return ("?"); ! 306: t2 = cp-sp; ! 307: return (formtab[t1][t2]); ! 308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.