📄 i386-pinsn.c
字号:
static char *obufp;static char scratchbuf[100];static unsigned char *start_codep;static unsigned char *codep;static int mod;static int rm;static int reg;static void oappend ();static char *names32[]={ "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",};static char *names16[] = { "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",};static char *names8[] = { "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",};static char *names_seg[] = { "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",};struct dis386 grps[][8] = { /* GRP1b */ { { "addb", Eb, Ib }, { "orb", Eb, Ib }, { "adcb", Eb, Ib }, { "sbbb", Eb, Ib }, { "andb", Eb, Ib }, { "subb", Eb, Ib }, { "xorb", Eb, Ib }, { "cmpb", Eb, Ib } }, /* GRP1S */ { { "addS", Ev, Iv }, { "orS", Ev, Iv }, { "adcS", Ev, Iv }, { "sbbS", Ev, Iv }, { "andS", Ev, Iv }, { "subS", Ev, Iv }, { "xorS", Ev, Iv }, { "cmpS", Ev, Iv } }, /* GRP1Ss */ { { "addS", Ev, sIb }, { "orS", Ev, sIb }, { "adcS", Ev, sIb }, { "sbbS", Ev, sIb }, { "andS", Ev, sIb }, { "subS", Ev, sIb }, { "xorS", Ev, sIb }, { "cmpS", Ev, sIb } }, /* GRP2b */ { { "rolb", Eb, Ib }, { "rorb", Eb, Ib }, { "rclb", Eb, Ib }, { "rcrb", Eb, Ib }, { "shlb", Eb, Ib }, { "shrb", Eb, Ib }, { "(bad)" }, { "sarb", Eb, Ib }, }, /* GRP2S */ { { "rolS", Ev, Ib }, { "rorS", Ev, Ib }, { "rclS", Ev, Ib }, { "rcrS", Ev, Ib }, { "shlS", Ev, Ib }, { "shrS", Ev, Ib }, { "(bad)" }, { "sarS", Ev, Ib }, }, /* GRP2b_one */ { { "rolb", Eb }, { "rorb", Eb }, { "rclb", Eb }, { "rcrb", Eb }, { "shlb", Eb }, { "shrb", Eb }, { "(bad)" }, { "sarb", Eb }, }, /* GRP2S_one */ { { "rolS", Ev }, { "rorS", Ev }, { "rclS", Ev }, { "rcrS", Ev }, { "shlS", Ev }, { "shrS", Ev }, { "(bad)" }, { "sarS", Ev }, }, /* GRP2b_cl */ { { "rolb", Eb, CL }, { "rorb", Eb, CL }, { "rclb", Eb, CL }, { "rcrb", Eb, CL }, { "shlb", Eb, CL }, { "shrb", Eb, CL }, { "(bad)" }, { "sarb", Eb, CL }, }, /* GRP2S_cl */ { { "rolS", Ev, CL }, { "rorS", Ev, CL }, { "rclS", Ev, CL }, { "rcrS", Ev, CL }, { "shlS", Ev, CL }, { "shrS", Ev, CL }, { "(bad)" }, { "sarS", Ev, CL } }, /* GRP3b */ { { "testb", Eb, Ib }, { "(bad)", Eb }, { "notb", Eb }, { "negb", Eb }, { "mulb", AL, Eb }, { "imulb", AL, Eb }, { "divb", AL, Eb }, { "idivb", AL, Eb } }, /* GRP3S */ { { "testS", Ev, Iv }, { "(bad)" }, { "notS", Ev }, { "negS", Ev }, { "mulS", eAX, Ev }, { "imulS", eAX, Ev }, { "divS", eAX, Ev }, { "idivS", eAX, Ev }, }, /* GRP4 */ { { "incb", Eb }, { "decb", Eb }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, }, /* GRP5 */ { { "incS", Ev }, { "decS", Ev }, { "call", indirEv }, { "lcall", indirEv }, { "jmp", indirEv }, { "ljmp", indirEv }, { "pushS", Ev }, { "(bad)" }, }, /* GRP6 */ { { "sldt", Ew }, { "str", Ew }, { "lldt", Ew }, { "ltr", Ew }, { "verr", Ew }, { "verw", Ew }, { "(bad)" }, { "(bad)" } }, /* GRP7 */ { { "sgdt", Ew }, { "sidt", Ew }, { "lgdt", Ew }, { "lidt", Ew }, { "smsw", Ew }, { "(bad)" }, { "lmsw", Ew }, { "(bad)" }, }, /* GRP8 */ { { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "btS", Ev, Ib }, { "btsS", Ev, Ib }, { "btrS", Ev, Ib }, { "btcS", Ev, Ib }, }};#define PREFIX_REPZ 1#define PREFIX_REPNZ 2#define PREFIX_LOCK 4#define PREFIX_CS 8#define PREFIX_SS 0x10#define PREFIX_DS 0x20#define PREFIX_ES 0x40#define PREFIX_FS 0x80#define PREFIX_GS 0x100#define PREFIX_DATA 0x200#define PREFIX_ADR 0x400#define PREFIX_FWAIT 0x800static int prefixes;static voidckprefix (){ prefixes = 0; while (1) { switch (*codep) { case 0xf3: prefixes |= PREFIX_REPZ; break; case 0xf2: prefixes |= PREFIX_REPNZ; break; case 0xf0: prefixes |= PREFIX_LOCK; break; case 0x2e: prefixes |= PREFIX_CS; break; case 0x36: prefixes |= PREFIX_SS; break; case 0x3e: prefixes |= PREFIX_DS; break; case 0x26: prefixes |= PREFIX_ES; break; case 0x64: prefixes |= PREFIX_FS; break; case 0x65: prefixes |= PREFIX_GS; break; case 0x66: prefixes |= PREFIX_DATA; break; case 0x67: prefixes |= PREFIX_ADR; break; case 0x9b: prefixes |= PREFIX_FWAIT; break; default: return; } codep++; }}static int dflag;static int aflag; static char op1out[100], op2out[100], op3out[100];static int op_address[3], op_ad, op_index[3];static int start_pc;extern void fputs_filtered ();/* * disassemble the first instruction in 'inbuf'. You have to make * sure all of the bytes of the instruction are filled in. * On the 386's of 1988, the maximum length of an instruction is 15 bytes. * (see topic "Redundant prefixes" in the "Differences from 8086" * section of the "Virtual 8086 Mode" chapter.) * 'pc' should be the address of this instruction, it will * be used to print the target address if this is a relative jump or call * 'outbuf' gets filled in with the disassembled instruction. it should * be long enough to hold the longest disassembled instruction. * 100 bytes is certainly enough, unless symbol printing is added later * The function returns the length of this instruction in bytes. */inti386dis (pc, inbuf, stream) int pc; unsigned char *inbuf; FILE *stream;{ struct dis386 *dp; int i; int enter_instruction; char *first, *second, *third; int needcomma; obuf[0] = 0; op1out[0] = 0; op2out[0] = 0; op3out[0] = 0; op_index[0] = op_index[1] = op_index[2] = -1; start_pc = pc; start_codep = inbuf; codep = inbuf; ckprefix (); if (*codep == 0xc8) enter_instruction = 1; else enter_instruction = 0; obufp = obuf; if (prefixes & PREFIX_REPZ) oappend ("repz "); if (prefixes & PREFIX_REPNZ) oappend ("repnz "); if (prefixes & PREFIX_LOCK) oappend ("lock "); if ((prefixes & PREFIX_FWAIT) && ((*codep < 0xd8) || (*codep > 0xdf))) { /* fwait not followed by floating point instruction */ fputs_filtered ("fwait", stream); return (1); } /* these would be initialized to 0 if disassembling for 8086 or 286 */ dflag = 1; aflag = 1; if (prefixes & PREFIX_DATA) dflag ^= 1; if (prefixes & PREFIX_ADR) { aflag ^= 1; oappend ("addr16 "); } if (*codep == 0x0f) dp = &dis386_twobyte[*++codep]; else dp = &dis386[*codep]; codep++; mod = (*codep >> 6) & 3; reg = (*codep >> 3) & 7; rm = *codep & 7; if (dp->name == NULL && dp->bytemode1 == FLOATCODE) { dofloat (); } else { if (dp->name == NULL) dp = &grps[dp->bytemode1][reg]; putop (dp->name); obufp = op1out; op_ad = 2; if (dp->op1) (*dp->op1)(dp->bytemode1); obufp = op2out; op_ad = 1; if (dp->op2) (*dp->op2)(dp->bytemode2); obufp = op3out; op_ad = 0; if (dp->op3) (*dp->op3)(dp->bytemode3); } obufp = obuf + strlen (obuf); for (i = strlen (obuf); i < 6; i++) oappend (" "); oappend (" "); fputs_filtered (obuf, stream); /* enter instruction is printed with operands in the * same order as the intel book; everything else * is printed in reverse order */ if (enter_instruction) { 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) print_address (op_address[op_index[0]], stream); else fputs_filtered (first, stream); needcomma = 1; } if (*second) { if (needcomma) fputs_filtered (",", stream); if (op_index[1] != -1) print_address (op_address[op_index[1]], stream); else fputs_filtered (second, stream); needcomma = 1; } if (*third) { if (needcomma) fputs_filtered (",", stream); if (op_index[2] != -1) print_address (op_address[op_index[2]], stream); else fputs_filtered (third, stream); } return (codep - inbuf);}char *float_mem[] = { /* d8 */ "fadds", "fmuls", "fcoms", "fcomps", "fsubs", "fsubrs", "fdivs", "fdivrs", /* d9 */ "flds", "(bad)", "fsts", "fstps", "fldenv", "fldcw", "fNstenv", "fNstcw", /* da */ "fiaddl", "fimull", "ficoml", "ficompl", "fisubl", "fisubrl", "fidivl", "fidivrl", /* db */ "fildl", "(bad)", "fistl", "fistpl", "(bad)", "fldt", "(bad)", "fstpt", /* dc */ "faddl", "fmull", "fcoml", "fcompl", "fsubl", "fsubrl", "fdivl", "fdivrl", /* dd */ "fldl", "(bad)", "fstl", "fstpl", "frstor", "(bad)", "fNsave", "fNstsw", /* de */ "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr", /* df */ "fild", "(bad)", "fist", "fistp", "fbld", "fildll", "fbstp", "fistpll",};#define ST OP_ST, 0#define STi OP_STi, 0int OP_ST(), OP_STi();#define FGRPd9_2 NULL, NULL, 0#define FGRPd9_4 NULL, NULL, 1#define FGRPd9_5 NULL, NULL, 2#define FGRPd9_6 NULL, NULL, 3#define FGRPd9_7 NULL, NULL, 4#define FGRPda_5 NULL, NULL, 5#define FGRPdb_4 NULL, NULL, 6#define FGRPde_3 NULL, NULL, 7#define FGRPdf_4 NULL, NULL, 8struct dis386 float_reg[][8] = { /* d8 */ { { "fadd", ST, STi }, { "fmul", ST, STi }, { "fcom", STi }, { "fcomp", STi }, { "fsub", ST, STi }, { "fsubr", ST, STi }, { "fdiv", ST, STi }, { "fdivr", ST, STi }, }, /* d9 */ { { "fld", STi }, { "fxch", STi }, { FGRPd9_2 }, { "(bad)" }, { FGRPd9_4 }, { FGRPd9_5 }, { FGRPd9_6 }, { FGRPd9_7 }, }, /* da */ { { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { FGRPda_5 }, { "(bad)" }, { "(bad)" }, }, /* db */ { { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { FGRPdb_4 }, { "(bad)" }, { "(bad)" }, { "(bad)" }, }, /* dc */ { { "fadd", STi, ST }, { "fmul", STi, ST }, { "(bad)" }, { "(bad)" }, { "fsub", STi, ST }, { "fsubr", STi, ST }, { "fdiv", STi, ST }, { "fdivr", STi, ST }, }, /* dd */ { { "ffree", STi }, { "(bad)" }, { "fst", STi }, { "fstp", STi }, { "fucom", STi }, { "fucomp", STi }, { "(bad)" }, { "(bad)" }, }, /* de */ { { "faddp", STi, ST }, { "fmulp", STi, ST }, { "(bad)" }, { FGRPde_3 }, { "fsubp", STi, ST }, { "fsubrp", STi, ST }, { "fdivp", STi, ST }, { "fdivrp", STi, ST }, }, /* df */ { { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" }, { FGRPdf_4 }, { "(bad)" }, { "(bad)" }, { "(bad)" }, },};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)", },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -