📄 i386-dis.c
字号:
info->private_data = (PTR) &priv; priv.max_fetched = priv.the_buffer; priv.insn_start = pc; obuf[0] = 0; op1out[0] = 0; op2out[0] = 0; op3out[0] = 0; op_index[0] = op_index[1] = op_index[2] = -1; the_info = info; start_pc = pc; start_codep = priv.the_buffer; codep = priv.the_buffer; if (setjmp (priv.bailout) != 0) { const char *name; /* Getting here means we tried for data but didn't get it. That means we have an incomplete instruction of some sort. Just print the first byte as a prefix or a .byte pseudo-op. */ if (codep > priv.the_buffer) { name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); if (name != NULL) (*info->fprintf_func) (info->stream, "%s", name); else { /* Just print the first byte as a .byte instruction. */ (*info->fprintf_func) (info->stream, ".byte 0x%x", (unsigned int) priv.the_buffer[0]); } return 1; } return -1; } obufp = obuf; ckprefix (); insn_codep = codep; sizeflag = priv.orig_sizeflag; FETCH_DATA (info, codep + 1); two_source_ops = (*codep == 0x62) || (*codep == 0xc8); if ((prefixes & PREFIX_FWAIT) && ((*codep < 0xd8) || (*codep > 0xdf))) { const char *name; /* fwait not followed by floating point instruction. Print the first prefix, which is probably fwait itself. */ name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); if (name == NULL) name = INTERNAL_DISASSEMBLER_ERROR; (*info->fprintf_func) (info->stream, "%s", name); return 1; } if (*codep == 0x0f) { FETCH_DATA (info, codep + 2); dp = &dis386_twobyte[*++codep]; need_modrm = twobyte_has_modrm[*codep]; uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep]; } else { dp = &dis386[*codep]; need_modrm = onebyte_has_modrm[*codep]; uses_SSE_prefix = 0; } codep++; if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ)) { oappend ("repz "); used_prefixes |= PREFIX_REPZ; } if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ)) { oappend ("repnz "); used_prefixes |= PREFIX_REPNZ; } if (prefixes & PREFIX_LOCK) { oappend ("lock "); used_prefixes |= PREFIX_LOCK; } if (prefixes & PREFIX_ADDR) { sizeflag ^= AFLAG; if (dp->bytemode3 != loop_jcxz_mode || intel_syntax) { if ((sizeflag & AFLAG) || mode_64bit) oappend ("addr32 "); else oappend ("addr16 "); used_prefixes |= PREFIX_ADDR; } } if (!uses_SSE_prefix && (prefixes & PREFIX_DATA)) { sizeflag ^= DFLAG; if (dp->bytemode3 == cond_jump_mode && dp->bytemode1 == v_mode && !intel_syntax) { if (sizeflag & DFLAG) oappend ("data32 "); else oappend ("data16 "); used_prefixes |= PREFIX_DATA; } } if (need_modrm) { FETCH_DATA (info, codep + 1); mod = (*codep >> 6) & 3; reg = (*codep >> 3) & 7; rm = *codep & 7; } if (dp->name == NULL && dp->bytemode1 == FLOATCODE) { dofloat (sizeflag); } else { int index; if (dp->name == NULL) { switch (dp->bytemode1) { case USE_GROUPS: dp = &grps[dp->bytemode2][reg]; break; case USE_PREFIX_USER_TABLE: index = 0; used_prefixes |= (prefixes & PREFIX_REPZ); if (prefixes & PREFIX_REPZ) index = 1; else { used_prefixes |= (prefixes & PREFIX_DATA); if (prefixes & PREFIX_DATA) index = 2; else { used_prefixes |= (prefixes & PREFIX_REPNZ); if (prefixes & PREFIX_REPNZ) index = 3; } } dp = &prefix_user_table[dp->bytemode2][index]; break; case X86_64_SPECIAL: dp = &x86_64_table[dp->bytemode2][mode_64bit]; break; default: oappend (INTERNAL_DISASSEMBLER_ERROR); break; } } if (putop (dp->name, sizeflag) == 0) { obufp = op1out; op_ad = 2; if (dp->op1) (*dp->op1) (dp->bytemode1, sizeflag); obufp = op2out; op_ad = 1; if (dp->op2) (*dp->op2) (dp->bytemode2, sizeflag); obufp = op3out; op_ad = 0; if (dp->op3) (*dp->op3) (dp->bytemode3, sizeflag); } } /* See if any prefixes were not used. If so, print the first one separately. If we don't do this, we'll wind up printing an instruction stream which does not precisely correspond to the bytes we are disassembling. */ if ((prefixes & ~used_prefixes) != 0) { const char *name; name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); if (name == NULL) name = INTERNAL_DISASSEMBLER_ERROR; (*info->fprintf_func) (info->stream, "%s", name); return 1; } if (rex & ~rex_used) { const char *name; name = prefix_name (rex | 0x40, priv.orig_sizeflag); if (name == NULL) name = INTERNAL_DISASSEMBLER_ERROR; (*info->fprintf_func) (info->stream, "%s ", name); } obufp = obuf + strlen (obuf); for (i = strlen (obuf); i < 6; i++) oappend (" "); oappend (" "); (*info->fprintf_func) (info->stream, "%s", obuf); /* The enter and bound instructions are printed with operands in the same order as the intel book; everything else is printed in reverse order. */ if (intel_syntax || two_source_ops) { first = op1out; second = op2out; third = op3out; op_ad = op_index[0]; op_index[0] = op_index[2]; op_index[2] = op_ad; } else { first = op3out; second = op2out; third = op1out; } needcomma = 0; if (*first) { if (op_index[0] != -1 && !op_riprel[0]) (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info); else (*info->fprintf_func) (info->stream, "%s", first); needcomma = 1; } if (*second) { if (needcomma) (*info->fprintf_func) (info->stream, ","); if (op_index[1] != -1 && !op_riprel[1]) (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info); else (*info->fprintf_func) (info->stream, "%s", second); needcomma = 1; } if (*third) { if (needcomma) (*info->fprintf_func) (info->stream, ","); if (op_index[2] != -1 && !op_riprel[2]) (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info); else (*info->fprintf_func) (info->stream, "%s", third); } for (i = 0; i < 3; i++) if (op_index[i] != -1 && op_riprel[i]) { (*info->fprintf_func) (info->stream, " # "); (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep + op_address[op_index[i]]), info); } return codep - priv.the_buffer;}static const char *float_mem[] = { /* d8 */ "fadd{s||s|}", "fmul{s||s|}", "fcom{s||s|}", "fcomp{s||s|}", "fsub{s||s|}", "fsubr{s||s|}", "fdiv{s||s|}", "fdivr{s||s|}", /* d9 */ "fld{s||s|}", "(bad)", "fst{s||s|}", "fstp{s||s|}", "fldenv", "fldcw", "fNstenv", "fNstcw", /* da */ "fiadd{l||l|}", "fimul{l||l|}", "ficom{l||l|}", "ficomp{l||l|}", "fisub{l||l|}", "fisubr{l||l|}", "fidiv{l||l|}", "fidivr{l||l|}", /* db */ "fild{l||l|}", "(bad)", "fist{l||l|}", "fistp{l||l|}", "(bad)", "fld{t||t|}", "(bad)", "fstp{t||t|}", /* dc */ "fadd{l||l|}", "fmul{l||l|}", "fcom{l||l|}", "fcomp{l||l|}", "fsub{l||l|}", "fsubr{l||l|}", "fdiv{l||l|}", "fdivr{l||l|}", /* dd */ "fld{l||l|}", "(bad)", "fst{l||l|}", "fstp{l||l|}", "frstor", "(bad)", "fNsave", "fNstsw", /* de */ "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr", /* df */ "fild", "(bad)", "fist", "fistp", "fbld", "fild{ll||ll|}", "fbstp", "fistpll",};#define ST OP_ST, 0#define STi OP_STi, 0#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0static const struct dis386 float_reg[][8] = { /* d8 */ { { "fadd", ST, STi, XX }, { "fmul", ST, STi, XX }, { "fcom", STi, XX, XX }, { "fcomp", STi, XX, XX }, { "fsub", ST, STi, XX }, { "fsubr", ST, STi, XX }, { "fdiv", ST, STi, XX }, { "fdivr", ST, STi, XX }, }, /* d9 */ { { "fld", STi, XX, XX }, { "fxch", STi, XX, XX }, { FGRPd9_2 }, { "(bad)", XX, XX, XX }, { FGRPd9_4 }, { FGRPd9_5 }, { FGRPd9_6 }, { FGRPd9_7 }, }, /* da */ { { "fcmovb", ST, STi, XX }, { "fcmove", ST, STi, XX }, { "fcmovbe",ST, STi, XX }, { "fcmovu", ST, STi, XX }, { "(bad)", XX, XX, XX }, { FGRPda_5 }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, }, /* db */ { { "fcmovnb",ST, STi, XX }, { "fcmovne",ST, STi, XX }, { "fcmovnbe",ST, STi, XX }, { "fcmovnu",ST, STi, XX }, { FGRPdb_4 }, { "fucomi", ST, STi, XX }, { "fcomi", ST, STi, XX }, { "(bad)", XX, XX, XX }, }, /* dc */ { { "fadd", STi, ST, XX }, { "fmul", STi, ST, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX },#if UNIXWARE_COMPAT { "fsub", STi, ST, XX }, { "fsubr", STi, ST, XX }, { "fdiv", STi, ST, XX }, { "fdivr", STi, ST, XX },#else { "fsubr", STi, ST, XX }, { "fsub", STi, ST, XX }, { "fdivr", STi, ST, XX }, { "fdiv", STi, ST, XX },#endif }, /* dd */ { { "ffree", STi, XX, XX }, { "(bad)", XX, XX, XX }, { "fst", STi, XX, XX }, { "fstp", STi, XX, XX }, { "fucom", STi, XX, XX }, { "fucomp", STi, XX, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, }, /* de */ { { "faddp", STi, ST, XX }, { "fmulp", STi, ST, XX }, { "(bad)", XX, XX, XX }, { FGRPde_3 },#if UNIXWARE_COMPAT { "fsubp", STi, ST, XX }, { "fsubrp", STi, ST, XX }, { "fdivp", STi, ST, XX }, { "fdivrp", STi, ST, XX },#else { "fsubrp", STi, ST, XX }, { "fsubp", STi, ST, XX }, { "fdivrp", STi, ST, XX }, { "fdivp", STi, ST, XX },#endif }, /* df */ { { "ffreep", STi, XX, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { "(bad)", XX, XX, XX }, { FGRPdf_4 }, { "fucomip",ST, STi, XX }, { "fcomip", ST, STi, XX }, { "(bad)", XX, XX, XX }, },};static char *fgrps[][8] = { /* d9_2 0 */ { "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", }, /* d9_4 1 */ { "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", }, /* d9_5 2 */ { "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", }, /* d9_6 3 */ { "f2xm1","fyl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -