📄 m68k-dis.c
字号:
break; case '~': mask = M (0,0,1,1,1,1,1,1,1,0,0,0); break; case '%': mask = M (1,1,1,1,1,1,1,1,1,0,0,0); break; case ';': mask = M (1,0,1,1,1,1,1,1,1,1,1,1); break; case '@': mask = M (1,0,1,1,1,1,1,1,1,1,1,0); break; case '!': mask = M (0,0,1,0,0,1,1,1,1,1,1,0); break; case '&': mask = M (0,0,1,0,0,1,1,1,1,0,0,0); break; case '$': mask = M (1,0,1,1,1,1,1,1,1,0,0,0); break; case '?': mask = M (1,0,1,0,0,1,1,1,1,0,0,0); break; case '/': mask = M (1,0,1,0,0,1,1,1,1,1,1,0); break; case '|': mask = M (0,0,1,0,0,1,1,1,1,1,1,0); break; case '>': mask = M (0,0,1,0,1,1,1,1,1,0,0,0); break; case '<': mask = M (0,0,1,1,0,1,1,1,1,1,1,0); break; case 'm': mask = M (1,1,1,1,1,0,0,0,0,0,0,0); break; case 'n': mask = M (0,0,0,0,0,1,0,0,0,1,0,0); break; case 'o': mask = M (0,0,0,0,0,0,1,1,1,0,1,1); break; case 'p': mask = M (1,1,1,1,1,1,0,0,0,0,0,0); break; case 'q': mask = M (1,0,1,1,1,1,0,0,0,0,0,0); break; case 'v': mask = M (1,0,1,1,1,1,0,1,1,0,0,0); break; case 'b': mask = M (1,0,1,1,1,1,0,0,0,1,0,0); break; case 'w': mask = M (0,0,1,1,1,1,0,0,0,1,0,0); break; case 'y': mask = M (0,0,1,0,0,1,0,0,0,0,0,0); break; case 'z': mask = M (0,0,1,0,0,1,0,0,0,1,0,0); break; case '4': mask = M (0,0,1,1,1,1,0,0,0,0,0,0); break; default: abort (); }#undef M mode = (val >> 3) & 7; if (mode == 7) mode += val & 7; return (mask & (1 << mode)) != 0;}/* Print a base register REGNO and displacement DISP, on INFO->STREAM. REGNO = -1 for pc, -2 for none (suppressed). */static voidprint_base (int regno, bfd_vma disp, disassemble_info *info){ if (regno == -1) { (*info->fprintf_func) (info->stream, "%%pc@("); (*info->print_address_func) (disp, info); } else { char buf[50]; if (regno == -2) (*info->fprintf_func) (info->stream, "@("); else if (regno == -3) (*info->fprintf_func) (info->stream, "%%zpc@("); else (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]); sprintf_vma (buf, disp); (*info->fprintf_func) (info->stream, "%s", buf); }}/* Print an indexed argument. The base register is BASEREG (-1 for pc). P points to extension word, in buffer. ADDR is the nominal core address of that extension word. */static unsigned char *print_indexed (int basereg, unsigned char *p, bfd_vma addr, disassemble_info *info){ int word; static char *const scales[] = { "", ":2", ":4", ":8" }; bfd_vma base_disp; bfd_vma outer_disp; char buf[40]; char vmabuf[50]; word = NEXTWORD (p); /* Generate the text for the index register. Where this will be output is not yet determined. */ sprintf (buf, "%s:%c%s", reg_names[(word >> 12) & 0xf], (word & 0x800) ? 'l' : 'w', scales[(word >> 9) & 3]); /* Handle the 68000 style of indexing. */ if ((word & 0x100) == 0) { base_disp = word & 0xff; if ((base_disp & 0x80) != 0) base_disp -= 0x100; if (basereg == -1) base_disp += addr; print_base (basereg, base_disp, info); (*info->fprintf_func) (info->stream, ",%s)", buf); return p; } /* Handle the generalized kind. */ /* First, compute the displacement to add to the base register. */ if (word & 0200) { if (basereg == -1) basereg = -3; else basereg = -2; } if (word & 0100) buf[0] = '\0'; base_disp = 0; switch ((word >> 4) & 3) { case 2: base_disp = NEXTWORD (p); break; case 3: base_disp = NEXTLONG (p); } if (basereg == -1) base_disp += addr; /* Handle single-level case (not indirect). */ if ((word & 7) == 0) { print_base (basereg, base_disp, info); if (buf[0] != '\0') (*info->fprintf_func) (info->stream, ",%s", buf); (*info->fprintf_func) (info->stream, ")"); return p; } /* Two level. Compute displacement to add after indirection. */ outer_disp = 0; switch (word & 3) { case 2: outer_disp = NEXTWORD (p); break; case 3: outer_disp = NEXTLONG (p); } print_base (basereg, base_disp, info); if ((word & 4) == 0 && buf[0] != '\0') { (*info->fprintf_func) (info->stream, ",%s", buf); buf[0] = '\0'; } sprintf_vma (vmabuf, outer_disp); (*info->fprintf_func) (info->stream, ")@(%s", vmabuf); if (buf[0] != '\0') (*info->fprintf_func) (info->stream, ",%s", buf); (*info->fprintf_func) (info->stream, ")"); return p;}/* Returns number of bytes "eaten" by the operand, or return -1 if an invalid operand was found, or -2 if an opcode tabe error was found. ADDR is the pc for this arg to be relative to. */static intprint_insn_arg (const char *d, unsigned char *buffer, unsigned char *p0, bfd_vma addr, disassemble_info *info){ int val = 0; int place = d[1]; unsigned char *p = p0; int regno; const char *regname; unsigned char *p1; double flval; int flt_p; bfd_signed_vma disp; unsigned int uval; switch (*d) { case 'c': /* Cache identifier. */ { static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" }; val = fetch_arg (buffer, place, 2, info); (*info->fprintf_func) (info->stream, cacheFieldName[val]); break; } case 'a': /* Address register indirect only. Cf. case '+'. */ { (*info->fprintf_func) (info->stream, "%s@", reg_names[fetch_arg (buffer, place, 3, info) + 8]); break; } case '_': /* 32-bit absolute address for move16. */ { uval = NEXTULONG (p); (*info->print_address_func) (uval, info); break; } case 'C': (*info->fprintf_func) (info->stream, "%%ccr"); break; case 'S': (*info->fprintf_func) (info->stream, "%%sr"); break; case 'U': (*info->fprintf_func) (info->stream, "%%usp"); break; case 'E': (*info->fprintf_func) (info->stream, "%%acc"); break; case 'G': (*info->fprintf_func) (info->stream, "%%macsr"); break; case 'H': (*info->fprintf_func) (info->stream, "%%mask"); break; case 'J': { /* FIXME: There's a problem here, different m68k processors call the same address different names. This table can't get it right because it doesn't know which processor it's disassembling for. */ static const struct { char *name; int value; } names[] = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002}, {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005}, {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008}, {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802}, {"%msp", 0x803}, {"%isp", 0x804}, {"%flashbar", 0xc04}, {"%rambar", 0xc05}, /* mcf528x added these. */ /* Should we be calling this psr like we do in case 'Y'? */ {"%mmusr",0x805}, {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}}; val = fetch_arg (buffer, place, 12, info); for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--) if (names[regno].value == val) { (*info->fprintf_func) (info->stream, "%s", names[regno].name); break; } if (regno < 0) (*info->fprintf_func) (info->stream, "%d", val); } break; case 'Q': val = fetch_arg (buffer, place, 3, info); /* 0 means 8, except for the bkpt instruction... */ if (val == 0 && d[1] != 's') val = 8; (*info->fprintf_func) (info->stream, "#%d", val); break; case 'x': val = fetch_arg (buffer, place, 3, info); /* 0 means -1. */ if (val == 0) val = -1; (*info->fprintf_func) (info->stream, "#%d", val); break; case 'M': if (place == 'h') { static char *const scalefactor_name[] = { "<<", ">>" }; val = fetch_arg (buffer, place, 1, info); (*info->fprintf_func) (info->stream, scalefactor_name[val]); } else { val = fetch_arg (buffer, place, 8, info); if (val & 0x80) val = val - 0x100; (*info->fprintf_func) (info->stream, "#%d", val); } break; case 'T': val = fetch_arg (buffer, place, 4, info); (*info->fprintf_func) (info->stream, "#%d", val); break; case 'D': (*info->fprintf_func) (info->stream, "%s", reg_names[fetch_arg (buffer, place, 3, info)]); break; case 'A': (*info->fprintf_func) (info->stream, "%s", reg_names[fetch_arg (buffer, place, 3, info) + 010]); break; case 'R': (*info->fprintf_func) (info->stream, "%s", reg_names[fetch_arg (buffer, place, 4, info)]); break; case 'r': regno = fetch_arg (buffer, place, 4, info); if (regno > 7) (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]); else (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]); break; case 'F': (*info->fprintf_func) (info->stream, "%%fp%d", fetch_arg (buffer, place, 3, info)); break; case 'O': val = fetch_arg (buffer, place, 6, info); if (val & 0x20) (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]); else (*info->fprintf_func) (info->stream, "%d", val); break; case '+': (*info->fprintf_func) (info->stream, "%s@+", reg_names[fetch_arg (buffer, place, 3, info) + 8]); break; case '-': (*info->fprintf_func) (info->stream, "%s@-", reg_names[fetch_arg (buffer, place, 3, info) + 8]); break; case 'k': if (place == 'k') (*info->fprintf_func) (info->stream, "{%s}", reg_names[fetch_arg (buffer, place, 3, info)]); else if (place == 'C') { val = fetch_arg (buffer, place, 7, info); if (val > 63) /* This is a signed constant. */ val -= 128; (*info->fprintf_func) (info->stream, "{#%d}", val); } else return -2; break; case '#': case '^': p1 = buffer + (*d == '#' ? 2 : 4); if (place == 's') val = fetch_arg (buffer, place, 4, info); else if (place == 'C') val = fetch_arg (buffer, place, 7, info); else if (place == '8') val = fetch_arg (buffer, place, 3, info); else if (place == '3') val = fetch_arg (buffer, place, 8, info); else if (place == 'b') val = NEXTBYTE (p1); else if (place == 'w' || place == 'W') val = NEXTWORD (p1); else if (place == 'l') val = NEXTLONG (p1); else return -2; (*info->fprintf_func) (info->stream, "#%d", val); break; case 'B':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -