📄 i386-dis.c
字号:
#define cond_jump_mode 8
#define loop_jcxz_mode 9
#define es_reg 100
#define cs_reg 101
#define ss_reg 102
#define ds_reg 103
#define fs_reg 104
#define gs_reg 105
#define eAX_reg 108
#define eCX_reg 109
#define eDX_reg 110
#define eBX_reg 111
#define eSP_reg 112
#define eBP_reg 113
#define eSI_reg 114
#define eDI_reg 115
#define al_reg 116
#define cl_reg 117
#define dl_reg 118
#define bl_reg 119
#define ah_reg 120
#define ch_reg 121
#define dh_reg 122
#define bh_reg 123
#define ax_reg 124
#define cx_reg 125
#define dx_reg 126
#define bx_reg 127
#define sp_reg 128
#define bp_reg 129
#define si_reg 130
#define di_reg 131
#define rAX_reg 132
#define rCX_reg 133
#define rDX_reg 134
#define rBX_reg 135
#define rSP_reg 136
#define rBP_reg 137
#define rSI_reg 138
#define rDI_reg 139
#define indir_dx_reg 150
#define FLOATCODE 1
#define USE_GROUPS 2
#define USE_PREFIX_USER_TABLE 3
#define X86_64_SPECIAL 4
#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
struct dis386 {
const char *name;
op_rtn op1;
int bytemode1;
op_rtn op2;
int bytemode2;
op_rtn op3;
int bytemode3;
};
/* Upper case letters in the instruction names here are macros.
'A' => print 'b' if no register operands or suffix_always is true
'B' => print 'b' if suffix_always is true
'E' => print 'e' if 32-bit form of jcxz
'F' => print 'w' or 'l' depending on address size prefix (loop insns)
'H' => print ",pt" or ",pn" branch hint
'L' => print 'l' if suffix_always is true
'N' => print 'n' if instruction has no wait "prefix"
'O' => print 'd', or 'o'
'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
. or suffix_always is true. print 'q' if rex prefix is present.
'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
. is true
'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
'S' => print 'w', 'l' or 'q' if suffix_always is true
'T' => print 'q' in 64bit mode and behave as 'P' otherwise
'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
'X' => print 's', 'd' depending on data16 prefix (for XMM)
'W' => print 'b' or 'w' ("w" or "de" in intel mode)
'Y' => 'q' if instruction has an REX 64bit overwrite prefix
Many of the above letters print nothing in Intel mode. See "putop"
for the details.
Braces '{' and '}', and vertical bars '|', indicate alternative
mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
modes. In cases where there are only two alternatives, the X86_64
instruction is reserved, and "(bad)" is printed.
*/
static const struct dis386 dis386[] = {
/* 00 */
{ "addB", Eb, Gb, XX },
{ "addS", Ev, Gv, XX },
{ "addB", Gb, Eb, XX },
{ "addS", Gv, Ev, XX },
{ "addB", AL, Ib, XX },
{ "addS", eAX, Iv, XX },
{ "push{T|}", es, XX, XX },
{ "pop{T|}", es, XX, XX },
/* 08 */
{ "orB", Eb, Gb, XX },
{ "orS", Ev, Gv, XX },
{ "orB", Gb, Eb, XX },
{ "orS", Gv, Ev, XX },
{ "orB", AL, Ib, XX },
{ "orS", eAX, Iv, XX },
{ "push{T|}", cs, XX, XX },
{ "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
/* 10 */
{ "adcB", Eb, Gb, XX },
{ "adcS", Ev, Gv, XX },
{ "adcB", Gb, Eb, XX },
{ "adcS", Gv, Ev, XX },
{ "adcB", AL, Ib, XX },
{ "adcS", eAX, Iv, XX },
{ "push{T|}", ss, XX, XX },
{ "popT|}", ss, XX, XX },
/* 18 */
{ "sbbB", Eb, Gb, XX },
{ "sbbS", Ev, Gv, XX },
{ "sbbB", Gb, Eb, XX },
{ "sbbS", Gv, Ev, XX },
{ "sbbB", AL, Ib, XX },
{ "sbbS", eAX, Iv, XX },
{ "push{T|}", ds, XX, XX },
{ "pop{T|}", ds, XX, XX },
/* 20 */
{ "andB", Eb, Gb, XX },
{ "andS", Ev, Gv, XX },
{ "andB", Gb, Eb, XX },
{ "andS", Gv, Ev, XX },
{ "andB", AL, Ib, XX },
{ "andS", eAX, Iv, XX },
{ "(bad)", XX, XX, XX }, /* SEG ES prefix */
{ "daa{|}", XX, XX, XX },
/* 28 */
{ "subB", Eb, Gb, XX },
{ "subS", Ev, Gv, XX },
{ "subB", Gb, Eb, XX },
{ "subS", Gv, Ev, XX },
{ "subB", AL, Ib, XX },
{ "subS", eAX, Iv, XX },
{ "(bad)", XX, XX, XX }, /* SEG CS prefix */
{ "das{|}", XX, XX, XX },
/* 30 */
{ "xorB", Eb, Gb, XX },
{ "xorS", Ev, Gv, XX },
{ "xorB", Gb, Eb, XX },
{ "xorS", Gv, Ev, XX },
{ "xorB", AL, Ib, XX },
{ "xorS", eAX, Iv, XX },
{ "(bad)", XX, XX, XX }, /* SEG SS prefix */
{ "aaa{|}", XX, XX, XX },
/* 38 */
{ "cmpB", Eb, Gb, XX },
{ "cmpS", Ev, Gv, XX },
{ "cmpB", Gb, Eb, XX },
{ "cmpS", Gv, Ev, XX },
{ "cmpB", AL, Ib, XX },
{ "cmpS", eAX, Iv, XX },
{ "(bad)", XX, XX, XX }, /* SEG DS prefix */
{ "aas{|}", XX, XX, XX },
/* 40 */
{ "inc{S|}", RMeAX, XX, XX },
{ "inc{S|}", RMeCX, XX, XX },
{ "inc{S|}", RMeDX, XX, XX },
{ "inc{S|}", RMeBX, XX, XX },
{ "inc{S|}", RMeSP, XX, XX },
{ "inc{S|}", RMeBP, XX, XX },
{ "inc{S|}", RMeSI, XX, XX },
{ "inc{S|}", RMeDI, XX, XX },
/* 48 */
{ "dec{S|}", RMeAX, XX, XX },
{ "dec{S|}", RMeCX, XX, XX },
{ "dec{S|}", RMeDX, XX, XX },
{ "dec{S|}", RMeBX, XX, XX },
{ "dec{S|}", RMeSP, XX, XX },
{ "dec{S|}", RMeBP, XX, XX },
{ "dec{S|}", RMeSI, XX, XX },
{ "dec{S|}", RMeDI, XX, XX },
/* 50 */
{ "pushS", RMrAX, XX, XX },
{ "pushS", RMrCX, XX, XX },
{ "pushS", RMrDX, XX, XX },
{ "pushS", RMrBX, XX, XX },
{ "pushS", RMrSP, XX, XX },
{ "pushS", RMrBP, XX, XX },
{ "pushS", RMrSI, XX, XX },
{ "pushS", RMrDI, XX, XX },
/* 58 */
{ "popS", RMrAX, XX, XX },
{ "popS", RMrCX, XX, XX },
{ "popS", RMrDX, XX, XX },
{ "popS", RMrBX, XX, XX },
{ "popS", RMrSP, XX, XX },
{ "popS", RMrBP, XX, XX },
{ "popS", RMrSI, XX, XX },
{ "popS", RMrDI, XX, XX },
/* 60 */
{ "pusha{P|}", XX, XX, XX },
{ "popa{P|}", XX, XX, XX },
{ "bound{S|}", Gv, Ma, XX },
{ X86_64_0 },
{ "(bad)", XX, XX, XX }, /* seg fs */
{ "(bad)", XX, XX, XX }, /* seg gs */
{ "(bad)", XX, XX, XX }, /* op size prefix */
{ "(bad)", XX, XX, XX }, /* adr size prefix */
/* 68 */
{ "pushT", Iq, XX, XX },
{ "imulS", Gv, Ev, Iv },
{ "pushT", sIb, XX, XX },
{ "imulS", Gv, Ev, sIb },
{ "ins{b||b|}", Yb, indirDX, XX },
{ "ins{R||R|}", Yv, indirDX, XX },
{ "outs{b||b|}", indirDX, Xb, XX },
{ "outs{R||R|}", indirDX, Xv, XX },
/* 70 */
{ "joH", Jb, XX, cond_jump_flag },
{ "jnoH", Jb, XX, cond_jump_flag },
{ "jbH", Jb, XX, cond_jump_flag },
{ "jaeH", Jb, XX, cond_jump_flag },
{ "jeH", Jb, XX, cond_jump_flag },
{ "jneH", Jb, XX, cond_jump_flag },
{ "jbeH", Jb, XX, cond_jump_flag },
{ "jaH", Jb, XX, cond_jump_flag },
/* 78 */
{ "jsH", Jb, XX, cond_jump_flag },
{ "jnsH", Jb, XX, cond_jump_flag },
{ "jpH", Jb, XX, cond_jump_flag },
{ "jnpH", Jb, XX, cond_jump_flag },
{ "jlH", Jb, XX, cond_jump_flag },
{ "jgeH", Jb, XX, cond_jump_flag },
{ "jleH", Jb, XX, cond_jump_flag },
{ "jgH", Jb, XX, cond_jump_flag },
/* 80 */
{ GRP1b },
{ GRP1S },
{ "(bad)", XX, XX, XX },
{ GRP1Ss },
{ "testB", Eb, Gb, XX },
{ "testS", Ev, Gv, XX },
{ "xchgB", Eb, Gb, XX },
{ "xchgS", Ev, Gv, XX },
/* 88 */
{ "movB", Eb, Gb, XX },
{ "movS", Ev, Gv, XX },
{ "movB", Gb, Eb, XX },
{ "movS", Gv, Ev, XX },
{ "movQ", Ev, Sw, XX },
{ "leaS", Gv, M, XX },
{ "movQ", Sw, Ev, XX },
{ "popU", Ev, XX, XX },
/* 90 */
{ "nop", XX, XX, XX },
/* FIXME: NOP with REPz prefix is called PAUSE. */
{ "xchgS", RMeCX, eAX, XX },
{ "xchgS", RMeDX, eAX, XX },
{ "xchgS", RMeBX, eAX, XX },
{ "xchgS", RMeSP, eAX, XX },
{ "xchgS", RMeBP, eAX, XX },
{ "xchgS", RMeSI, eAX, XX },
{ "xchgS", RMeDI, eAX, XX },
/* 98 */
{ "cW{tR||tR|}", XX, XX, XX },
{ "cR{tO||tO|}", XX, XX, XX },
{ "lcall{T|}", Ap, XX, XX },
{ "(bad)", XX, XX, XX }, /* fwait */
{ "pushfT", XX, XX, XX },
{ "popfT", XX, XX, XX },
{ "sahf{|}", XX, XX, XX },
{ "lahf{|}", XX, XX, XX },
/* a0 */
{ "movB", AL, Ob64, XX },
{ "movS", eAX, Ov64, XX },
{ "movB", Ob64, AL, XX },
{ "movS", Ov64, eAX, XX },
{ "movs{b||b|}", Yb, Xb, XX },
{ "movs{R||R|}", Yv, Xv, XX },
{ "cmps{b||b|}", Xb, Yb, XX },
{ "cmps{R||R|}", Xv, Yv, XX },
/* a8 */
{ "testB", AL, Ib, XX },
{ "testS", eAX, Iv, XX },
{ "stosB", Yb, AL, XX },
{ "stosS", Yv, eAX, XX },
{ "lodsB", AL, Xb, XX },
{ "lodsS", eAX, Xv, XX },
{ "scasB", AL, Yb, XX },
{ "scasS", eAX, Yv, XX },
/* b0 */
{ "movB", RMAL, Ib, XX },
{ "movB", RMCL, Ib, XX },
{ "movB", RMDL, Ib, XX },
{ "movB", RMBL, Ib, XX },
{ "movB", RMAH, Ib, XX },
{ "movB", RMCH, Ib, XX },
{ "movB", RMDH, Ib, XX },
{ "movB", RMBH, Ib, XX },
/* b8 */
{ "movS", RMeAX, Iv64, XX },
{ "movS", RMeCX, Iv64, XX },
{ "movS", RMeDX, Iv64, XX },
{ "movS", RMeBX, Iv64, XX },
{ "movS", RMeSP, Iv64, XX },
{ "movS", RMeBP, Iv64, XX },
{ "movS", RMeSI, Iv64, XX },
{ "movS", RMeDI, Iv64, XX },
/* c0 */
{ GRP2b },
{ GRP2S },
{ "retT", Iw, XX, XX },
{ "retT", XX, XX, XX },
{ "les{S|}", Gv, Mp, XX },
{ "ldsS", Gv, Mp, XX },
{ "movA", Eb, Ib, XX },
{ "movQ", Ev, Iv, XX },
/* c8 */
{ "enterT", Iw, Ib, XX },
{ "leaveT", XX, XX, XX },
{ "lretP", Iw, XX, XX },
{ "lretP", XX, XX, XX },
{ "int3", XX, XX, XX },
{ "int", Ib, XX, XX },
{ "into{|}", XX, XX, XX },
{ "iretP", XX, XX, XX },
/* d0 */
{ GRP2b_one },
{ GRP2S_one },
{ GRP2b_cl },
{ GRP2S_cl },
{ "aam{|}", sIb, XX, XX },
{ "aad{|}", sIb, XX, XX },
{ "(bad)", XX, XX, XX },
{ "xlat", DSBX, XX, XX },
/* d8 */
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
{ FLOAT },
/* e0 */
{ "loopneFH", Jb, XX, loop_jcxz_flag },
{ "loopeFH", Jb, XX, loop_jcxz_flag },
{ "loopFH", Jb, XX, loop_jcxz_flag },
{ "jEcxzH", Jb, XX, loop_jcxz_flag },
{ "inB", AL, Ib, XX },
{ "inS", eAX, Ib, XX },
{ "outB", Ib, AL, XX },
{ "outS", Ib, eAX, XX },
/* e8 */
{ "callT", Jv, XX, XX },
{ "jmpT", Jv, XX, XX },
{ "ljmp{T|}", Ap, XX, XX },
{ "jmp", Jb, XX, XX },
{ "inB", AL, indirDX, XX },
{ "inS", eAX, indirDX, XX },
{ "outB", indirDX, AL, XX },
{ "outS", indirDX, eAX, XX },
/* f0 */
{ "(bad)", XX, XX, XX }, /* lock prefix */
{ "(bad)", XX, XX, XX },
{ "(bad)", XX, XX, XX }, /* repne */
{ "(bad)", XX, XX, XX }, /* repz */
{ "hlt", XX, XX, XX },
{ "cmc", XX, XX, XX },
{ GRP3b },
{ GRP3S },
/* f8 */
{ "clc", XX, XX, XX },
{ "stc", XX, XX, XX },
{ "cli", XX, XX, XX },
{ "sti", XX, XX, XX },
{ "cld", XX, XX, XX },
{ "std", XX, XX, XX },
{ GRP4 },
{ GRP5 },
};
static const struct dis386 dis386_twobyte[] = {
/* 00 */
{ GRP6 },
{ GRP7 },
{ "larS", Gv, Ew, XX },
{ "lslS", Gv, Ew, XX },
{ "(bad)", XX, XX, XX },
{ "syscall", XX, XX, XX },
{ "clts", XX, XX, XX },
{ "sysretP", XX, XX, XX },
/* 08 */
{ "invd", XX, XX, XX },
{ "wbinvd", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ "ud2a", XX, XX, XX },
{ "(bad)", XX, XX, XX },
{ GRPAMD },
{ "femms", XX, XX, XX },
{ "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
/* 10 */
{ PREGRP8 },
{ PREGRP9 },
{ "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
{ "movlpX", EX, XM, SIMD_Fixup, 'h' },
{ "unpcklpX", XM, EX, XX },
{ "unpckhpX", XM, EX, XX },
{ "movhpX", XM, EX, SIMD_Fixup, 'l' },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -