📄 2db.c
字号:
{ case 0x10: break; case 0x20: if (i16(ip, &ap->disp) < 0) return -1; break; case 0x30: if (i32(ip, &ap->disp) < 0) return -1; break; default: ip->errmsg = "bad EA displacement"; return -1; } switch (ext&0x03) /* outer displacement */ { case 0x02: /* 16 bit displacement */ return i16(ip, &ap->outer); case 0x03: /* 32 bit displacement */ return i32(ip, &ap->outer); default: break; } return 1;}static intea(Inst *ip, int ea, Operand *ap, int mode){ int type, size; type = 0; ap->ext = 0; switch((ea>>3)&0x07) { case 0x00: ap->eatype = Dreg; type = Dn; break; case 0x01: ap->eatype = Areg; type = An; break; case 0x02: ap->eatype = AInd; type = Ind; break; case 0x03: ap->eatype = APinc; type = Pinc; break; case 0x04: ap->eatype = APdec; type = Pdec; break; case 0x05: ap->eatype = ADisp; type = Bdisp; if (i16(ip, &ap->disp) < 0) return -1; break; case 0x06: ap->eatype = BXD; type = Bdisp; if (getdisp(ip, ap) < 0) return -1; break; case 0x07: switch(ea&0x07) { case 0x00: type = Abs; ap->eatype = ABS; if (i16(ip, &ap->immediate) < 0) return -1; break; case 0x01: type = Abs; ap->eatype = ABS; if (i32(ip, &ap->immediate) < 0) return -1; break; case 0x02: type = PCrel; ap->eatype = PDisp; if (i16(ip, &ap->disp) < 0) return -1; break; case 0x03: type = PCrel; ap->eatype = PXD; if (getdisp(ip, ap) < 0) return -1; break; case 0x04: type = Imm; if (getimm(ip, ap, mode) < 0) return -1; break; default: ip->errmsg = "bad EA mode"; return -1; } } /* Allowable floating point EAs are restricted for packed, * extended, and double precision operands */ if (mode == EAFLT) { size = (ip->raw[1]>>10)&0x07; if (size == 2 || size == 3 || size == 5) mode = EAM; else mode = EADI; } if (!(validea[mode]&type)) { ip->errmsg = "invalid EA"; return -1; } return 1;}static intdecode(Inst *ip, Optable *op){ int i, t, mode; Operand *ap; short opcode; opcode = ip->raw[0]; for (i = 0; i < nelem(op->opdata) && op->opdata[i]; i++) { ap = &ip->and[i]; mode = op->opdata[i]; switch(mode) { case EAPI: /* normal EA modes */ case EACA: case EACAD: case EACAPI: case EACAPD: case EAMA: case EADA: case EAA: case EAC: case EACPI: case EACD: case EAD: case EAM: case EAM_B: case EADI: case EADI_L: case EADI_W: case EAALL: case EAALL_L: case EAALL_W: case EAALL_B: case EAFLT: if (ea(ip, opcode&0x3f, ap, mode) < 0) return -1; break; case EADDA: /* stupid bit flop required */ t = ((opcode>>9)&0x07)|((opcode>>3)&0x38); if (ea(ip, t, ap, EADA)< 0) return -1; break; case BREAC: /* EAC JMP or CALL operand */ if (ea(ip, opcode&0x3f, ap, EAC) < 0) return -1; break; case OP8: /* weird movq instruction */ ap->eatype = IMM; ap->immediate = opcode&0xff; if (opcode&0x80) ap->immediate |= ~0xff; break; case I8: /* must be two-word opcode */ ap->eatype = IMM; ap->immediate = ip->raw[1]&0xff; if (ap->immediate&0x80) ap->immediate |= ~0xff; break; case I16: /* 16 bit immediate */ case BR16: ap->eatype = IMM; if (i16(ip, &ap->immediate) < 0) return -1; break; case C16: /* CAS2 16 bit immediate */ ap->eatype = IMM; if (i16(ip, &ap->immediate) < 0) return -1; if (ap->immediate & 0x0e38) { ip->errmsg = "bad CAS2W operand"; return 0; } break; case I32: /* 32 bit immediate */ case BR32: ap->eatype = IMM; if (i32(ip, &ap->immediate) < 0) return -1; break; case IV: /* immediate data depends on size field */ if (getimm(ip, ap, IV) < 0) return -1; break; case BR8: /* branch displacement format */ ap->eatype = IMM; ap->immediate = opcode&0xff; if (ap->immediate == 0) { if (i16(ip, &ap->immediate) < 0) return -1; } else if (ap->immediate == 0xff) { if (i32(ip, &ap->immediate) < 0) return -1; } else if (ap->immediate & 0x80) ap->immediate |= ~0xff; break; case STACK: /* Dummy operand type for Return instructions */ default: break; } } return 1;}static Optable *instruction(Inst *ip){ ushort opcode, op2; Optable *op; int class; ip->n = 0; if (getword(ip, ip->addr) < 0) return 0; opcode = ip->raw[0]; if (get2(mymap, ip->addr+2, &op2) < 0) op2 = 0; class = (opcode>>12)&0x0f; for (op = optables[class]; op && op->format; op++) { if (op->opcode != (opcode&op->mask0)) continue; if (op->op2 != (op2&op->mask1)) continue; if (op->mask1) ip->raw[ip->n++] = op2; return op; } ip->errmsg = "Invalid opcode"; return 0;}#pragma varargck argpos bprint 2static voidbprint(Inst *i, char *fmt, ...){ va_list arg; va_start(arg, fmt); i->curr = vseprint(i->curr, i->end, fmt, arg); va_end(arg);}static char *regname[] ={ "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "PC", "SB"};static voidplocal(Inst *ip, Operand *ap){ int ret; long offset; uvlong moved; Symbol s; offset = ap->disp; if (!findsym(ip->addr, CTEXT, &s)) goto none; moved = pc2sp(ip->addr); if (moved == -1) goto none; if (offset > moved) { /* above frame - must be argument */ offset -= moved; ret = getauto(&s, offset-mach->szaddr, CPARAM, &s); } else /* below frame - must be automatic */ ret = getauto(&s, moved-offset, CPARAM, &s); if (ret) bprint(ip, "%s+%lux", s.name, offset); elsenone: bprint(ip, "%lux", ap->disp);}/* * this guy does all the work of printing the base and index component * of an EA. */static intpidx(Inst *ip, int ext, int reg, char *bfmt, char *ifmt, char *nobase){ char *s; int printed; char buf[512]; printed = 1; if (ext&0x80) { /* Base suppressed */ if (reg == 16) bprint(ip, bfmt, "(ZPC)"); else if (nobase) bprint(ip, nobase); else printed = 0; } else /* format base reg */ bprint(ip, bfmt, regname[reg]); if (ext & 0x40) /* index suppressed */ return printed; switch ((ext>>9)&0x03) { case 0x01: s = "*2"; break; case 0x02: s = "*4"; break; case 0x03: s = "*8"; break; default: if (ext&0x80) s = "*1"; else s = ""; break; } sprint(buf, "%s.%c%s", regname[(ext>>12)&0x0f], (ext&0x800) ? 'L' : 'W', s); if (!printed) bprint(ip, ifmt, buf); else bprint(ip, "(%s)", buf); return 1;}static voidprindex(Inst *ip, int reg, Operand *ap){ short ext; int left; int disp; left = ip->end-ip->curr; if (left <= 0) return; ext = ap->ext; disp = ap->disp; /* look for static base register references */ if ((ext&0xa0) == 0x20 && reg == 14 && mach->sb && disp) { reg = 17; /* "A6" -> "SB" */ disp += mach->sb; } if ((ext&0x100) == 0) { /* brief form */ if (reg == 15) plocal(ip, ap); else if (disp) ip->curr += symoff(ip->curr, left, disp, CANY); pidx(ip, ext&0xff00, reg, "(%s)", "(%s)", 0); return; } switch(ext&0x3f) /* bd size, && i/is */ { case 0x10: if (!pidx(ip, ext, reg, "(%s)", "(%s)", 0)) bprint(ip, "#0"); break; case 0x11: if (pidx(ip, ext, reg, "((%s)", "((%s)", 0)) bprint(ip, ")"); else bprint(ip, "#0"); break; case 0x12: case 0x13: ip->curr += symoff(ip->curr, left, ap->outer, CANY); if (pidx(ip, ext, reg, "((%s)", "((%s)", 0)) bprint(ip, ")"); break; case 0x15: if (!pidx(ip, ext, reg, "((%s))", "(%s)", 0)) bprint(ip, "#0"); break; case 0x16: case 0x17: ip->curr += symoff(ip->curr, left, ap->outer, CANY); pidx(ip, ext, reg, "((%s))", "(%s)", 0); break; case 0x20: case 0x30: if (reg == 15) plocal(ip, ap); else ip->curr += symoff(ip->curr, left, disp, CANY); pidx(ip, ext, reg, "(%s)", "(%s)", 0); break; case 0x21: case 0x31: *ip->curr++ = '('; if (reg == 15) plocal(ip, ap); else ip->curr += symoff(ip->curr, left-1, disp, CANY); pidx(ip, ext, reg, "(%s)", "(%s)", 0); bprint(ip, ")"); break; case 0x22: case 0x23: case 0x32: case 0x33: ip->curr += symoff(ip->curr, left, ap->outer, CANY); bprint(ip, "("); if (reg == 15) plocal(ip, ap); else ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY); pidx(ip, ext, reg, "(%s)", "(%s)", 0); bprint(ip, ")"); break; case 0x25: case 0x35: *ip->curr++ = '('; if (reg == 15) plocal(ip, ap); else ip->curr += symoff(ip->curr, left-1, disp, CANY); if (!pidx(ip, ext, reg, "(%s))", "(%s)", "())")) bprint(ip, ")"); break; case 0x26: case 0x27: case 0x36: case 0x37: ip->curr += symoff(ip->curr, left, ap->outer, CANY); bprint(ip, "("); if (reg == 15) plocal(ip, ap); else ip->curr += symoff(ip->curr, ip->end-ip->curr, disp, CANY); pidx(ip, ext, reg, "(%s))", "(%s)", "())"); break; default: bprint(ip, "??%x??", ext); ip->errmsg = "bad EA"; break; }}static voidpea(int reg, Inst *ip, Operand *ap){ int i, left; left = ip->end-ip->curr; if (left < 0) return; switch(ap->eatype) { case Dreg: bprint(ip, "R%d", reg); break; case Areg: bprint(ip, "A%d", reg); break; case AInd: bprint(ip, "(A%d)", reg); break; case APinc: bprint(ip, "(A%d)+", reg); break; case APdec: bprint(ip, "-(A%d)", reg); break; case PDisp: ip->curr += symoff(ip->curr, left, ip->addr+2+ap->disp, CANY); break; case PXD: prindex(ip, 16, ap); break; case ADisp: /* references off the static base */ if (reg == 6 && mach->sb && ap->disp) { ip->curr += symoff(ip->curr, left, ap->disp+mach->sb, CANY); bprint(ip, "(SB)"); break; } /* reference autos and parameters off the stack */ if (reg == 7) plocal(ip, ap); else ip->curr += symoff(ip->curr, left, ap->disp, CANY); bprint(ip, "(A%d)", reg); break; case BXD: prindex(ip, reg+8, ap); break; case ABS: ip->curr += symoff(ip->curr, left, ap->immediate, CANY); bprint(ip, "($0)"); break; case IMM: *ip->curr++ = '$'; ip->curr += symoff(ip->curr, left-1, ap->immediate, CANY); break; case IREAL: *ip->curr++ = '$'; ip->curr += beieeesftos(ip->curr, left-1, (void*) ap->floater); break; case IDBL: *ip->curr++ = '$'; ip->curr += beieeedftos(ip->curr, left-1, (void*) ap->floater); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -