/* * Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved. * Copyright (C) 2008-2013 Sourcefire, Inc. * * Authors: aCaB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #if HAVE_CONFIG_H #include "clamav-config.h" #endif #include #include #include #include "others.h" #include "disasmpriv.h" #include "disasm.h" #include "clamav.h" enum ADDRS { ADDR_REG_EAX, ADDR_REG_ECX, ADDR_REG_EDX, ADDR_REG_EBX, ADDR_REG_ESP, ADDR_REG_EBP, ADDR_REG_ESI, ADDR_REG_EDI, ADDR_REG_ES, ADDR_REG_CS, ADDR_REG_SS, ADDR_REG_DS, ADDR_REG_FS, ADDR_REG_GS, ADDR_MRM_GEN, ADDR_OFFSET, ADDR_MRM_GEN_EG, ADDR_MRM_GEN_GE, ADDR_MRM_GEN_GM, ADDR_MRM_GEN_ES, ADDR_MRM_GEN_SE, ADDR_MRM_EXTRA_1A, ADDR_MRM_EXTRA_1A_M, ADDR_MRM_GEN_RC, ADDR_MRM_GEN_RD, ADDR_MRM_GEN_CR, ADDR_MRM_GEN_DR, ADDR_IMMED, ADDR_RELJ, ADDR_IMPLICIT, ADDR_NOADDR }; enum ASIZE { SIZE_BYTE, SIZE_BYTEH, SIZE_WORD, SIZE_DWORD, SIZE_QWORD, SIZE_WD, SIZE_DF, SIZE_NOSIZE }; static const uint8_t sizemap[SIZE_NOSIZE+1][2] = { {1,1}, /* SIZE_BYTE */ {255,255}, /* SIZE_BYTEH */ {2,2}, /* SIZE_WORD */ {4,4}, /* SIZE_DWORD */ {255,255}, /* SIZE_QWORD */ {4,2}, /* SIZE_WD */ {6,4}, /* SIZE_DF */ {255,255} /* SIZE_NOSIZE */ }; static const uint8_t regmap[SIZE_DWORD+1][ADDR_REG_GS+1] = { /* SIZE_BYTE */ {X86_REG_AL, X86_REG_CL, X86_REG_DL, X86_REG_BL, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID}, /* SIZE_BYTEH */ {X86_REG_AH, X86_REG_CH, X86_REG_DH, X86_REG_BH, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID}, /* SIZE_WORD */ {X86_REG_AX, X86_REG_CX, X86_REG_DX, X86_REG_BX, X86_REG_SP, X86_REG_BP, X86_REG_SI, X86_REG_DI, X86_REG_ES, X86_REG_CS, X86_REG_SS, X86_REG_DS, X86_REG_FS, X86_REG_GS}, /* SIZE_DWORD */ {X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX, X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID} }; static const uint8_t mrm_regmap[3][8] = { /* SIZEB */ {X86_REG_AL, X86_REG_CL, X86_REG_DL, X86_REG_BL, X86_REG_AH, X86_REG_CH, X86_REG_DH, X86_REG_BH}, /* SIZEW */ {X86_REG_AX, X86_REG_CX, X86_REG_DX, X86_REG_BX, X86_REG_SP, X86_REG_BP, X86_REG_SI, X86_REG_DI}, /* SIZED */ {X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX, X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI} }; static const uint8_t mrm_sregmap[3][8] = { /* SIZEB */ {X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID}, /* SIZEW */ {X86_REG_ES, X86_REG_CS, X86_REG_SS, X86_REG_DS, X86_REG_FS, X86_REG_GS, X86_REG_INVALID, X86_REG_INVALID}, /* SIZED */ {X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID} }; static const uint8_t mrm_cregmap[3][8] = { /* SIZEB */ {X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID}, /* SIZEW */ {X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID}, /* SIZED */ {X86_REG_CR0, X86_REG_INVALID, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID} }; static const uint8_t mrm_dregmap[3][8] = { /* SIZEB */ {X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID}, /* SIZEW */ {X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID, X86_REG_INVALID}, /* SIZED */ {X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_INVALID, X86_REG_INVALID, X86_REG_DR6, X86_REG_DR7} }; static const struct { enum X86REGS r1; enum X86REGS r2; } mrm_regmapw[8] = { {X86_REG_BX, X86_REG_SI}, {X86_REG_BX, X86_REG_DI}, {X86_REG_BP, X86_REG_SI}, {X86_REG_BP, X86_REG_DI}, {X86_REG_SI, X86_REG_INVALID}, {X86_REG_DI, X86_REG_INVALID}, {X86_REG_BP, X86_REG_INVALID}, {X86_REG_BX, X86_REG_INVALID} }; static const struct { enum X86OPS op; enum DIS_SIZE size; } x87_mrm[8][8] = { /* D8 */ {{OP_FADD,SIZED},{OP_FMUL,SIZED},{OP_FCOM,SIZED},{OP_FCOMP,SIZED},{OP_FSUB,SIZED},{OP_FSUBR,SIZED},{OP_FDIV,SIZED},{OP_FDIVR,SIZED}}, /* D9 */ {{OP_FLD,SIZED},{OP_INVALID,SIZED},{OP_FST,SIZED},{OP_FSTP,SIZED},{OP_FLDENV,SIZEPTR},{OP_FLDCW,SIZEW},{OP_FSTENV,SIZEPTR},{OP_FSTCW,SIZEW}}, /* DA */ {{OP_FIADD,SIZED},{OP_FIMUL,SIZED},{OP_FICOM,SIZED},{OP_FICOMP,SIZED},{OP_FISUB,SIZED},{OP_FISUBR,SIZED},{OP_FIDIV,SIZED},{OP_FIDIVR,SIZED}}, /* DB */ {{OP_FILD,SIZED},{OP_FISTTP,SIZED},{OP_FIST,SIZED},{OP_FISTP,SIZED},{OP_INVALID,SIZED},{OP_FLD,SIZET},{OP_INVALID,SIZED},{OP_FSTP,SIZET} }, /* DC */ {{OP_FADD,SIZEQ},{OP_FMUL,SIZEQ},{OP_FCOM,SIZEQ},{OP_FCOMP,SIZEQ},{OP_FSUB,SIZEQ},{OP_FSUBR,SIZEQ},{OP_FDIV,SIZEQ},{OP_FDIVR,SIZEQ}}, /* DD */ {{OP_FLD,SIZEQ},{OP_FISTTP,SIZEQ},{OP_FST,SIZEQ},{OP_FSTP,SIZEQ},{OP_FRSTOR,SIZEPTR},{OP_INVALID,SIZED},{OP_FSAVE,SIZEPTR},{OP_FSTSW,SIZEW}}, /* DE */ {{OP_FIADD,SIZEW},{OP_FIMUL,SIZEW},{OP_FICOM,SIZEW},{OP_FICOMP,SIZEW},{OP_FISUB,SIZEW},{OP_FISUBR,SIZEW},{OP_FIDIV,SIZEW},{OP_FIDIVR,SIZEW}}, /* DF */ {{OP_FILD,SIZEW},{OP_FISTTP,SIZEW},{OP_FIST,SIZEW},{OP_FISTP,SIZEW},{OP_FBLD,SIZET},{OP_FILD,SIZEQ},{OP_FBSTP,SIZET},{OP_FISTP,SIZEQ}} }; static const struct { enum X86OPS op; enum { X87_NONE, X87_ONE, X87_S, X87_R } args; } x87_st[8][64] = { /* D8 */ { {OP_FADD,X87_S},{OP_FADD,X87_S},{OP_FADD,X87_S},{OP_FADD,X87_S},{OP_FADD,X87_S},{OP_FADD,X87_S},{OP_FADD,X87_S},{OP_FADD,X87_S}, {OP_FMUL,X87_S},{OP_FMUL,X87_S},{OP_FMUL,X87_S},{OP_FMUL,X87_S},{OP_FMUL,X87_S},{OP_FMUL,X87_S},{OP_FMUL,X87_S},{OP_FMUL,X87_S}, {OP_FCOM,X87_S},{OP_FCOM,X87_S},{OP_FCOM,X87_S},{OP_FCOM,X87_S},{OP_FCOM,X87_S},{OP_FCOM,X87_S},{OP_FCOM,X87_S},{OP_FCOM,X87_S}, {OP_FCOMP,X87_S},{OP_FCOMP,X87_S},{OP_FCOMP,X87_S},{OP_FCOMP,X87_S},{OP_FCOMP,X87_S},{OP_FCOMP,X87_S},{OP_FCOMP,X87_S},{OP_FCOMP,X87_S}, {OP_FSUB,X87_S},{OP_FSUB,X87_S},{OP_FSUB,X87_S},{OP_FSUB,X87_S},{OP_FSUB,X87_S},{OP_FSUB,X87_S},{OP_FSUB,X87_S},{OP_FSUB,X87_S}, {OP_FSUBR,X87_S},{OP_FSUBR,X87_S},{OP_FSUBR,X87_S},{OP_FSUBR,X87_S},{OP_FSUBR,X87_S},{OP_FSUBR,X87_S},{OP_FSUBR,X87_S},{OP_FSUBR,X87_S}, {OP_FDIV,X87_S},{OP_FDIV,X87_S},{OP_FDIV,X87_S},{OP_FDIV,X87_S},{OP_FDIV,X87_S},{OP_FDIV,X87_S},{OP_FDIV,X87_S},{OP_FDIV,X87_S}, {OP_FDIVR,X87_S},{OP_FDIVR,X87_S},{OP_FDIVR,X87_S},{OP_FDIVR,X87_S},{OP_FDIVR,X87_S},{OP_FDIVR,X87_S},{OP_FDIVR,X87_S},{OP_FDIVR,X87_S} }, /* D9 */ { {OP_FLD,X87_S},{OP_FLD,X87_S},{OP_FLD,X87_S},{OP_FLD,X87_S},{OP_FLD,X87_S},{OP_FLD,X87_S},{OP_FLD,X87_S},{OP_FLD,X87_S}, {OP_FXCH,X87_S},{OP_FXCH,X87_S},{OP_FXCH,X87_S},{OP_FXCH,X87_S},{OP_FXCH,X87_S},{OP_FXCH,X87_S},{OP_FXCH,X87_S},{OP_FXCH,X87_S}, {OP_FNOP,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_FCHS,X87_NONE},{OP_FABS,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_FTST,X87_NONE},{OP_FXAM,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_FLD1,X87_NONE},{OP_FLDL2T,X87_NONE},{OP_FLDL2E,X87_NONE},{OP_FLDPI,X87_NONE},{OP_FLDLG2,X87_NONE},{OP_FLDLN2,X87_NONE},{OP_FLDZ,X87_S},{OP_INVALID,X87_NONE}, {OP_F2XM1,X87_NONE},{OP_FYL2X,X87_NONE},{OP_FPTAN,X87_NONE},{OP_FPATAN,X87_NONE},{OP_FXTRACT,X87_NONE},{OP_FPREM1,X87_NONE},{OP_FDECSTP,X87_NONE},{OP_FINCSTP,X87_NONE}, {OP_FPREM,X87_NONE},{OP_FYL2XP1,X87_NONE},{OP_FSQRT,X87_NONE},{OP_FSINCOS,X87_NONE},{OP_FRNDINT,X87_NONE},{OP_FSCALE,X87_NONE},{OP_FSIN,X87_NONE},{OP_FCOS,X87_NONE} }, /* DA */ { {OP_FCMOVB,X87_S},{OP_FCMOVB,X87_S},{OP_FCMOVB,X87_S},{OP_FCMOVB,X87_S},{OP_FCMOVB,X87_S},{OP_FCMOVB,X87_S},{OP_FCMOVB,X87_S},{OP_FCMOVB,X87_S}, {OP_FCMOVE,X87_S},{OP_FCMOVE,X87_S},{OP_FCMOVE,X87_S},{OP_FCMOVE,X87_S},{OP_FCMOVE,X87_S},{OP_FCMOVE,X87_S},{OP_FCMOVE,X87_S},{OP_FCMOVE,X87_S}, {OP_FCMOVBE,X87_S},{OP_FCMOVBE,X87_S},{OP_FCMOVBE,X87_S},{OP_FCMOVBE,X87_S},{OP_FCMOVBE,X87_S},{OP_FCMOVBE,X87_S},{OP_FCMOVBE,X87_S},{OP_FCMOVBE,X87_S}, {OP_FCMOVU,X87_S},{OP_FCMOVU,X87_S},{OP_FCMOVU,X87_S},{OP_FCMOVU,X87_S},{OP_FCMOVU,X87_S},{OP_FCMOVU,X87_S},{OP_FCMOVU,X87_S},{OP_FCMOVU,X87_S}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_FUCOMPP,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE} }, /* DB */ { {OP_FCMOVNB,X87_S},{OP_FCMOVNB,X87_S},{OP_FCMOVNB,X87_S},{OP_FCMOVNB,X87_S},{OP_FCMOVNB,X87_S},{OP_FCMOVNB,X87_S},{OP_FCMOVNB,X87_S},{OP_FCMOVNB,X87_S}, {OP_FCMOVNE,X87_S},{OP_FCMOVNE,X87_S},{OP_FCMOVNE,X87_S},{OP_FCMOVNE,X87_S},{OP_FCMOVNE,X87_S},{OP_FCMOVNE,X87_S},{OP_FCMOVNE,X87_S},{OP_FCMOVNE,X87_S}, {OP_FCMOVNBE,X87_S},{OP_FCMOVNBE,X87_S},{OP_FCMOVNBE,X87_S},{OP_FCMOVNBE,X87_S},{OP_FCMOVNBE,X87_S},{OP_FCMOVNBE,X87_S},{OP_FCMOVNBE,X87_S},{OP_FCMOVNBE,X87_S}, {OP_FCMOVNU,X87_S},{OP_FCMOVNU,X87_S},{OP_FCMOVNU,X87_S},{OP_FCMOVNU,X87_S},{OP_FCMOVNU,X87_S},{OP_FCMOVNU,X87_S},{OP_FCMOVNU,X87_S},{OP_FCMOVNU,X87_S}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_FCLEX,X87_NONE},{OP_FINIT,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_FUCOMI,X87_S},{OP_FUCOMI,X87_S},{OP_FUCOMI,X87_S},{OP_FUCOMI,X87_S},{OP_FUCOMI,X87_S},{OP_FUCOMI,X87_S},{OP_FUCOMI,X87_S},{OP_FUCOMI,X87_S}, {OP_FCOMI,X87_S},{OP_FCOMI,X87_S},{OP_FCOMI,X87_S},{OP_FCOMI,X87_S},{OP_FCOMI,X87_S},{OP_FCOMI,X87_S},{OP_FCOMI,X87_S},{OP_FCOMI,X87_S}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE} }, /* DC */ { {OP_FADD,X87_R},{OP_FADD,X87_R},{OP_FADD,X87_R},{OP_FADD,X87_R},{OP_FADD,X87_R},{OP_FADD,X87_R},{OP_FADD,X87_R},{OP_FADD,X87_R}, {OP_FMUL,X87_R},{OP_FMUL,X87_R},{OP_FMUL,X87_R},{OP_FMUL,X87_R},{OP_FMUL,X87_R},{OP_FMUL,X87_R},{OP_FMUL,X87_R},{OP_FMUL,X87_R}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_FSUBR,X87_R},{OP_FSUBR,X87_R},{OP_FSUBR,X87_R},{OP_FSUBR,X87_R},{OP_FSUBR,X87_R},{OP_FSUBR,X87_R},{OP_FSUBR,X87_R},{OP_FSUBR,X87_R}, {OP_FSUB,X87_R},{OP_FSUB,X87_R},{OP_FSUB,X87_R},{OP_FSUB,X87_R},{OP_FSUB,X87_R},{OP_FSUB,X87_R},{OP_FSUB,X87_R},{OP_FSUB,X87_R}, {OP_FDIVR,X87_R},{OP_FDIVR,X87_R},{OP_FDIVR,X87_R},{OP_FDIVR,X87_R},{OP_FDIVR,X87_R},{OP_FDIVR,X87_R},{OP_FDIVR,X87_R},{OP_FDIVR,X87_R}, {OP_FDIV,X87_R},{OP_FDIV,X87_R},{OP_FDIV,X87_R},{OP_FDIV,X87_R},{OP_FDIV,X87_R},{OP_FDIV,X87_R},{OP_FDIV,X87_R},{OP_FDIV,X87_R} }, /* DD */ { {OP_FFREE,X87_ONE},{OP_FFREE,X87_ONE},{OP_FFREE,X87_ONE},{OP_FFREE,X87_ONE},{OP_FFREE,X87_ONE},{OP_FFREE,X87_ONE},{OP_FFREE,X87_ONE},{OP_FFREE,X87_ONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_FST,X87_ONE},{OP_FST,X87_ONE},{OP_FST,X87_ONE},{OP_FST,X87_ONE},{OP_FST,X87_ONE},{OP_FST,X87_ONE},{OP_FST,X87_ONE},{OP_FST,X87_ONE}, {OP_FSTP,X87_ONE},{OP_FSTP,X87_ONE},{OP_FSTP,X87_ONE},{OP_FSTP,X87_ONE},{OP_FSTP,X87_ONE},{OP_FSTP,X87_ONE},{OP_FSTP,X87_ONE},{OP_FSTP,X87_ONE}, {OP_FUCOM,X87_R},{OP_FUCOM,X87_R},{OP_FUCOM,X87_R},{OP_FUCOM,X87_R},{OP_FUCOM,X87_R},{OP_FUCOM,X87_R},{OP_FUCOM,X87_R},{OP_FUCOM,X87_R}, {OP_FUCOMP,X87_R},{OP_FUCOMP,X87_R},{OP_FUCOMP,X87_R},{OP_FUCOMP,X87_R},{OP_FUCOMP,X87_R},{OP_FUCOMP,X87_R},{OP_FUCOMP,X87_R},{OP_FUCOMP,X87_R}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE} }, /* DE */ { {OP_FADDP,X87_R},{OP_FADDP,X87_R},{OP_FADDP,X87_R},{OP_FADDP,X87_R},{OP_FADDP,X87_R},{OP_FADDP,X87_R},{OP_FADDP,X87_R},{OP_FADDP,X87_R}, {OP_FMULP,X87_R},{OP_FMULP,X87_R},{OP_FMULP,X87_R},{OP_FMULP,X87_R},{OP_FMULP,X87_R},{OP_FMULP,X87_R},{OP_FMULP,X87_R},{OP_FMULP,X87_R}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_FCOMPP,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_FSUBRP,X87_R},{OP_FSUBRP,X87_R},{OP_FSUBRP,X87_R},{OP_FSUBRP,X87_R},{OP_FSUBRP,X87_R},{OP_FSUBRP,X87_R},{OP_FSUBRP,X87_R},{OP_FSUBRP,X87_R}, {OP_FSUBP,X87_R},{OP_FSUBP,X87_R},{OP_FSUBP,X87_R},{OP_FSUBP,X87_R},{OP_FSUBP,X87_R},{OP_FSUBP,X87_R},{OP_FSUBP,X87_R},{OP_FSUBP,X87_R}, {OP_FDIVRP,X87_R},{OP_FDIVRP,X87_R},{OP_FDIVRP,X87_R},{OP_FDIVRP,X87_R},{OP_FDIVRP,X87_R},{OP_FDIVRP,X87_R},{OP_FDIVRP,X87_R},{OP_FDIVRP,X87_R}, {OP_FDIVP,X87_R},{OP_FDIVP,X87_R},{OP_FDIVP,X87_R},{OP_FDIVP,X87_R},{OP_FDIVP,X87_R},{OP_FDIVP,X87_R},{OP_FDIVP,X87_R},{OP_FDIVP,X87_R} }, /* DF */ { {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_INVALID,X87_NONE},{OP_FSTSW,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE}, {OP_FUCOMIP,X87_S},{OP_FUCOMIP,X87_S},{OP_FUCOMIP,X87_S},{OP_FUCOMIP,X87_S},{OP_FUCOMIP,X87_S},{OP_FUCOMIP,X87_S},{OP_FUCOMIP,X87_S},{OP_FUCOMIP,X87_S}, {OP_FCOMIP,X87_S},{OP_FCOMIP,X87_S},{OP_FCOMIP,X87_S},{OP_FCOMIP,X87_S},{OP_FCOMIP,X87_S},{OP_FCOMIP,X87_S},{OP_FCOMIP,X87_S},{OP_FCOMIP,X87_S}, {OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE},{OP_INVALID,X87_NONE} } }; static const char *mnemonic[] = { "Invalid opcode", "aaa", "aam", "aad", "aas", "add", "adc", "and", "arpl", "bound", "bsf", "bsr", "bswap", "bt", "btc", "btr", "bts", "call", "cdq", "cwd", "cwde", "cbw", "clc", "cld", "cli", "clts", "cmc", "cmovo", "cmovno", "cmovc", "cmovnc", "cmovz", "cmovnz", "cmovbe", "cmova", "cmovs", "cmovns", "cmovp", "cmovnp", "cmovl", "cmovge", "cmovle", "cmovg", "cmp", "cmpsd", "cmpsw", "cmpsb", "cmpxchg", "cmpxchg8b", "cpuid", "daa", "das", "dec", "div", "enter", "fwait", "hlt", "idiv", "imul", "inc", "in", "insd", "insw", "insb", "int", "int3", "into", "invd", "invlpg", "iret", "jo", "jno", "jc", "jnc", "jz", "jnz", "jbe", "ja", "js", "jns", "jp", "jnp", "jl", "jge", "jle", "jg", "jmp", "lahf", "lar", "lds", "les", "lfs", "lgs", "lea", "leave", "lgdt", "lidt", "lldt", "lock", "lodsd", "lodsw", "lodsb", "loop", "loope", "loopne", "jecxz", "lsl", "lss", "ltr", "mov", "movsd", "movsw", "movsb", "movsx", "movzx", "mul", "neg", "nop", "not", "or", "out", "outsd", "outsw", "outsb", "push", "pushad", "pusha", "pushfd", "pushf", "pop", "popad", "popfd", "popf", "rcl", "rcr", "rdmsr", "rdpmc", "rdtsc", "repe", "repne", "retf", "retn", "rol", "ror", "rsm", "sahf", "sar", "sbb", "scasd", "scasw", "scasb", "seto", "setno", "setc", "setnc", "setz", "setnz", "setbe", "seta", "sets", "setns", "setp", "setnp", "setl", "setge", "setle", "setg", "sgdt", "sidt", "shl", "shld", "shr", "shrd", "sldt", "stosd", "stosw", "stosb", "str", "stc", "std", "sti", "sub", "syscall", "sysenter", "sysexit", "sysret", "test", "ud2", "verr", "verrw", "wbinvd", "wrmsr", "xadd", "xchg", "xlat", "xor", "Operand Size", "Address Size", "Segment Override", "2byte escape", "FPU escape", "f2xm1", "fabs", "fadd", "faddp", "fbld", "fbstp", "fchs", "fclex", "fcmovb", "fcmovbe", "fcmove", "fcmovnb", "fcmovnbe", "fcmovne", "fcmovnu", "fcmovu", "fcom", "fcomi", "fcomip", "fcomp", "fcompp", "fcos", "fdecstp", "fdiv", "fdivp", "fdivr", "fdivrp", "ffree", "fiadd", "ficom", "ficomp", "fidiv", "fidivr", "fild", "fimul", "fincstp", "finit", "fist", "fistp", "fisttp", "fisub", "fisubr", "fld", "fld1", "fldcw", "fldenv", "fldl2e", "fldl2t", "fldlg2", "fldln2", "fldpi", "fldz", "fmul", "fmulp", "fnop", "fpatan", "fprem", "fprem1", "fptan", "frndint", "frstor", "fscale", "fsin", "fsincos", "fsqrt", "fsave", "fst", "fstcw", "fstenv", "fstp", "fstsw", "fsub", "fsubp", "fsubr", "fsubrp", "ftst", "fucom", "fucomi", "fucomip", "fucomp", "fucompp", "fxam", "fxch", "fxtract", "fyl2x", "fyl2xp1" }; struct OPCODES { enum ADDRS dmethod; enum ASIZE dsize; enum ADDRS smethod; enum ASIZE ssize; enum X86OPS op; }; static const struct { enum X86OPS op; enum { ADDSZ_ZERO, ADDSZ_ONE } addsz; } extra_1a[][8] = { /* 8f - pop */ {{OP_POP,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}}, /* 80-83 - GRP1 */ {{OP_ADD,0}, {OP_OR,0}, {OP_ADC,0}, {OP_SBB,0}, {OP_AND,0}, {OP_SUB,0}, {OP_XOR,0}, {OP_CMP,0}}, /* c0-c1, d0-d3 - GRP2 */ {{OP_ROL,0}, {OP_ROR,0}, {OP_RCL,0}, {OP_RCR,0}, {OP_SHL,0}, {OP_SHR,0}, {OP_INVALID,0}, {OP_SAR,0}}, /* fe - GRP4 */ {{OP_INC,0}, {OP_DEC,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}}, /* ff - GRP5 */ {{OP_INC,0}, {OP_DEC,0}, {OP_CALL,0}, {OP_CALL,1}, {OP_JMP,0}, {OP_JMP,1}, {OP_PUSH,0}, {OP_INVALID,0}}, /* c6-c7 GRP11 */ {{OP_MOV,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}}, /* f6-f7 - GRP3 */ {{OP_TEST,0}, {OP_INVALID,0}, {OP_NOT,0}, {OP_NEG,0}, {OP_MUL,0}, {OP_IMUL,0}, {OP_DIV,0}, {OP_IDIV,0}}, /* 0f00 - GRP6 */ {{OP_SLDT,0}, {OP_STR,0}, {OP_LLDT,0}, {OP_LTR,0}, {OP_VERR,0}, {OP_VERRW,0}, {OP_INVALID,0}, {OP_INVALID,0}}, /* 0f90 - SETO */ {{OP_SETO,0}, {OP_SETO,0}, {OP_SETO,0}, {OP_SETO,0}, {OP_SETO,0}, {OP_SETO,0}, {OP_SETO,0}, {OP_SETO,0}}, /* 0f91 - SETNO */ {{OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}}, /* 0f92 - SETC */ {{OP_SETC,0}, {OP_SETC,0}, {OP_SETC,0}, {OP_SETC,0}, {OP_SETC,0}, {OP_SETC,0}, {OP_SETC,0}, {OP_SETC,0}}, /* 0f93 - SETNC */ {{OP_SETNC,0}, {OP_SETNC,0}, {OP_SETNC,0}, {OP_SETNC,0}, {OP_SETNC,0}, {OP_SETNC,0}, {OP_SETNC,0}, {OP_SETNC,0}}, /* 0f94 - SETZ */ {{OP_SETZ,0}, {OP_SETZ,0}, {OP_SETZ,0}, {OP_SETZ,0}, {OP_SETZ,0}, {OP_SETZ,0}, {OP_SETZ,0}, {OP_SETZ,0}}, /* 0f95 - SETNZ */ {{OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}, {OP_SETNO,0}}, /* 0f96 - SETNB */ {{OP_SETBE,0}, {OP_SETBE,0}, {OP_SETBE,0}, {OP_SETBE,0}, {OP_SETBE,0}, {OP_SETBE,0}, {OP_SETBE,0}, {OP_SETBE,0}}, /* 0f97 - SETNA */ {{OP_SETA,0}, {OP_SETA,0}, {OP_SETA,0}, {OP_SETA,0}, {OP_SETA,0}, {OP_SETA,0}, {OP_SETA,0}, {OP_SETA,0}}, /* 0f98 - SETS */ {{OP_SETS,0}, {OP_SETS,0}, {OP_SETS,0}, {OP_SETS,0}, {OP_SETS,0}, {OP_SETS,0}, {OP_SETS,0}, {OP_SETS,0}}, /* 0f98 - SETNS */ {{OP_SETNS,0}, {OP_SETNS,0}, {OP_SETNS,0}, {OP_SETNS,0}, {OP_SETNS,0}, {OP_SETNS,0}, {OP_SETNS,0}, {OP_SETNS,0}}, /* 0f9a - SETP */ {{OP_SETP,0}, {OP_SETP,0}, {OP_SETP,0}, {OP_SETP,0}, {OP_SETP,0}, {OP_SETP,0}, {OP_SETP,0}, {OP_SETP,0}}, /* 0f9b - SETNP */ {{OP_SETNP,0}, {OP_SETNP,0}, {OP_SETNP,0}, {OP_SETNP,0}, {OP_SETNP,0}, {OP_SETNP,0}, {OP_SETNP,0}, {OP_SETNP,0}}, /* 0f9c - SETL */ {{OP_SETL,0}, {OP_SETL,0}, {OP_SETL,0}, {OP_SETL,0}, {OP_SETL,0}, {OP_SETL,0}, {OP_SETL,0}, {OP_SETL,0}}, /* 0f9d - SETGE */ {{OP_SETGE,0}, {OP_SETGE,0}, {OP_SETGE,0}, {OP_SETGE,0}, {OP_SETGE,0}, {OP_SETGE,0}, {OP_SETGE,0}, {OP_SETGE,0}}, /* 0f9e - SETLE */ {{OP_SETLE,0}, {OP_SETLE,0}, {OP_SETLE,0}, {OP_SETLE,0}, {OP_SETLE,0}, {OP_SETLE,0}, {OP_SETLE,0}, {OP_SETLE,0}}, /* 0f9f - SETG */ {{OP_SETG,0}, {OP_SETG,0}, {OP_SETG,0}, {OP_SETG,0}, {OP_SETG,0}, {OP_SETG,0}, {OP_SETG,0}, {OP_SETG,0}}, /* 0fba - GRP8 */ {{OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_BT,0}, {OP_BTS,0}, {OP_BTR,0}, {OP_BTC,0}}, /* 0fc7 - GRP9 */ {{OP_INVALID,0}, {OP_CMPXCHG8B,2}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}}, /* 0f01 - GRP7 */ {{OP_SGDT,3}, {OP_SIDT,3}, {OP_LGDT,3}, {OP_LIDT,3}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVALID,0}, {OP_INVLPG,0}}, }; #define PUSHOP(a,b,c,d,e,f) {b,c,d,e,f} #define OP_UNSUP OP_INVALID static const struct OPCODES x86ops[2][256] = {{ PUSHOP(0x00, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_ADD), PUSHOP(0x01, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_ADD), PUSHOP(0x02, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_ADD), PUSHOP(0x03, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_ADD), PUSHOP(0x04, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_ADD), PUSHOP(0x05, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_ADD), PUSHOP(0x06, ADDR_REG_ES, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x07, ADDR_REG_ES, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x08, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_OR), PUSHOP(0x09, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_OR), PUSHOP(0x0a, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_OR), PUSHOP(0x0b, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_OR), PUSHOP(0x0c, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_OR), PUSHOP(0x0d, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_OR), PUSHOP(0x0e, ADDR_REG_CS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x0f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_2BYTE), PUSHOP(0x10, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_ADC), PUSHOP(0x11, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_ADC), PUSHOP(0x12, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_ADC), PUSHOP(0x13, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_ADC), PUSHOP(0x14, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_ADC), PUSHOP(0x15, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_ADC), PUSHOP(0x16, ADDR_REG_SS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x17, ADDR_REG_SS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x18, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_SBB), PUSHOP(0x19, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_SBB), PUSHOP(0x1a, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_SBB), PUSHOP(0x1b, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_SBB), PUSHOP(0x1c, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_SBB), PUSHOP(0x1d, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_SBB), PUSHOP(0x1e, ADDR_REG_DS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x1f, ADDR_REG_DS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x20, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_AND), PUSHOP(0x21, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_AND), PUSHOP(0x22, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_AND), PUSHOP(0x23, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_AND), PUSHOP(0x24, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_AND), PUSHOP(0x25, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_AND), PUSHOP(0x26, ADDR_REG_ES, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_SEGMENT), PUSHOP(0x27, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_DAA), PUSHOP(0x28, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_SUB), PUSHOP(0x29, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_SUB), PUSHOP(0x2a, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_SUB), PUSHOP(0x2b, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_SUB), PUSHOP(0x2c, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_SUB), PUSHOP(0x2d, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_SUB), PUSHOP(0x2e, ADDR_REG_CS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_SEGMENT), PUSHOP(0x2f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_DAS), PUSHOP(0x30, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_XOR), PUSHOP(0x31, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_XOR), PUSHOP(0x32, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_XOR), PUSHOP(0x33, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_XOR), PUSHOP(0x34, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_XOR), PUSHOP(0x35, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_XOR), PUSHOP(0x36, ADDR_REG_SS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_SEGMENT), PUSHOP(0x37, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_AAA), PUSHOP(0x38, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_CMP), PUSHOP(0x39, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMP), PUSHOP(0x3a, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_CMP), PUSHOP(0x3b, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMP), PUSHOP(0x3c, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_CMP), PUSHOP(0x3d, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_CMP), PUSHOP(0x3e, ADDR_REG_DS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_SEGMENT), PUSHOP(0x3f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_AAS), PUSHOP(0x40, ADDR_REG_EAX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x41, ADDR_REG_ECX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x42, ADDR_REG_EDX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x43, ADDR_REG_EBX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x44, ADDR_REG_ESP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x45, ADDR_REG_EBP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x46, ADDR_REG_ESI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x47, ADDR_REG_EDI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INC), PUSHOP(0x48, ADDR_REG_EAX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x49, ADDR_REG_ECX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x4a, ADDR_REG_EDX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x4b, ADDR_REG_EBX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x4c, ADDR_REG_ESP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x4d, ADDR_REG_EBP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x4e, ADDR_REG_ESI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x4f, ADDR_REG_EDI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_DEC), PUSHOP(0x50, ADDR_REG_EAX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x51, ADDR_REG_ECX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x52, ADDR_REG_EDX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x53, ADDR_REG_EBX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x54, ADDR_REG_ESP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x55, ADDR_REG_EBP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x56, ADDR_REG_ESI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x57, ADDR_REG_EDI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x58, ADDR_REG_EAX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x59, ADDR_REG_ECX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x5a, ADDR_REG_EDX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x5b, ADDR_REG_EBX, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x5c, ADDR_REG_ESP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x5d, ADDR_REG_EBP, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x5e, ADDR_REG_ESI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x5f, ADDR_REG_EDI, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0x60, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSHAD), PUSHOP(0x61, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POPAD), PUSHOP(0x62, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BOUND), PUSHOP(0x63, ADDR_MRM_GEN_EG, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_ARPL), PUSHOP(0x64, ADDR_REG_FS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_SEGMENT), PUSHOP(0x65, ADDR_REG_GS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_SEGMENT), PUSHOP(0x66, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_OPSIZE), PUSHOP(0x67, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_ADDRSIZE), PUSHOP(0x68, ADDR_IMMED, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x69, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_IMUL), PUSHOP(0x6a, ADDR_IMMED, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0x6b, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_IMMED, SIZE_BYTE, OP_IMUL), PUSHOP(0x6c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INSB), PUSHOP(0x6d, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_INSD), PUSHOP(0x6e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_OUTSB), PUSHOP(0x6f, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_OUTSD), PUSHOP(0x70, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JO), PUSHOP(0x71, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JNO), PUSHOP(0x72, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JC), PUSHOP(0x73, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JNC), PUSHOP(0x74, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JZ), PUSHOP(0x75, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JNZ), PUSHOP(0x76, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JBE), PUSHOP(0x77, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JA), PUSHOP(0x78, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JS), PUSHOP(0x79, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JNS), PUSHOP(0x7a, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JP), PUSHOP(0x7b, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JNP), PUSHOP(0x7c, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JL), PUSHOP(0x7d, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JGE), PUSHOP(0x7e, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JLE), PUSHOP(0x7f, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JG), PUSHOP(0x80, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, 1), PUSHOP(0x81, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMMED, SIZE_WD, 1), PUSHOP(0x82, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, 1), PUSHOP(0x83, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMMED, SIZE_BYTE, 1), PUSHOP(0x84, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_TEST), PUSHOP(0x85, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_TEST), PUSHOP(0x86, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_XCHG), PUSHOP(0x87, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_XCHG), PUSHOP(0x88, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x89, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x8a, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x8b, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x8c, ADDR_MRM_GEN_ES, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x8d, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LEA), PUSHOP(0x8e, ADDR_MRM_GEN_SE, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x8f, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, 0), PUSHOP(0x90, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_NOP), PUSHOP(0x91, ADDR_REG_ECX, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_XCHG), PUSHOP(0x92, ADDR_REG_EDX, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_XCHG), PUSHOP(0x93, ADDR_REG_EBX, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_XCHG), PUSHOP(0x94, ADDR_REG_ESP, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_XCHG), PUSHOP(0x95, ADDR_REG_EBP, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_XCHG), PUSHOP(0x96, ADDR_REG_ESI, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_XCHG), PUSHOP(0x97, ADDR_REG_EDI, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_XCHG), PUSHOP(0x98, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CWDE), PUSHOP(0x99, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CDQ), PUSHOP(0x9a, ADDR_IMMED, SIZE_DF, ADDR_NOADDR, SIZE_NOSIZE, OP_CALL), PUSHOP(0x9b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FWAIT), PUSHOP(0x9c, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSHFD), PUSHOP(0x9d, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_POPFD), PUSHOP(0x9e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_SAHF), PUSHOP(0x9f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_LAHF), PUSHOP(0xa0, ADDR_REG_EAX, SIZE_BYTE, ADDR_OFFSET, SIZE_BYTE, OP_MOV), PUSHOP(0xa1, ADDR_REG_EAX, SIZE_WD, ADDR_OFFSET, SIZE_WD, OP_MOV), PUSHOP(0xa2, ADDR_OFFSET, SIZE_BYTE, ADDR_REG_EAX, SIZE_BYTE, OP_MOV), PUSHOP(0xa3, ADDR_OFFSET, SIZE_WD, ADDR_REG_EAX, SIZE_WD, OP_MOV), PUSHOP(0xa4, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSB), PUSHOP(0xa5, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSD), PUSHOP(0xa6, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_CMPSB), PUSHOP(0xa7, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMPSD), PUSHOP(0xa8, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_TEST), PUSHOP(0xa9, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_TEST), PUSHOP(0xaa, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_STOSB), PUSHOP(0xab, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_STOSD), PUSHOP(0xac, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_LODSB), PUSHOP(0xad, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LODSD), PUSHOP(0xae, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_SCASB), PUSHOP(0xaf, ADDR_NOADDR, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_SCASD), PUSHOP(0xb0, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb1, ADDR_REG_ECX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb2, ADDR_REG_EDX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb3, ADDR_REG_EBX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb4, ADDR_REG_EAX, SIZE_BYTEH, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb5, ADDR_REG_ECX, SIZE_BYTEH, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb6, ADDR_REG_EDX, SIZE_BYTEH, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb7, ADDR_REG_EBX, SIZE_BYTEH, ADDR_IMMED, SIZE_BYTE, OP_MOV), PUSHOP(0xb8, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xb9, ADDR_REG_ECX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xba, ADDR_REG_EDX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xbb, ADDR_REG_EBX, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xbc, ADDR_REG_ESP, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xbd, ADDR_REG_EBP, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xbe, ADDR_REG_ESI, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xbf, ADDR_REG_EDI, SIZE_WD, ADDR_IMMED, SIZE_WD, OP_MOV), PUSHOP(0xc0, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, 2), PUSHOP(0xc1, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMMED, SIZE_BYTE, 2), PUSHOP(0xc2, ADDR_IMMED, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_RETN), PUSHOP(0xc3, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_RETN), PUSHOP(0xc4, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LES), /* FIXME: mem size is F/D */ PUSHOP(0xc5, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LDS), /* FIXME: mem size is F/D */ PUSHOP(0xc6, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, 5), PUSHOP(0xc7, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMMED, SIZE_WD, 5), PUSHOP(0xc8, ADDR_IMMED, SIZE_WORD, ADDR_IMMED, SIZE_BYTE, OP_ENTER), PUSHOP(0xc9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_LEAVE), PUSHOP(0xca, ADDR_IMMED, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_RETF), PUSHOP(0xcb, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_RETF), PUSHOP(0xcc, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INT3), PUSHOP(0xcd, ADDR_IMMED, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_INT), PUSHOP(0xce, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INTO), PUSHOP(0xcf, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_IRET), PUSHOP(0xd0, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_IMPLICIT, 1, 2), PUSHOP(0xd1, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMPLICIT, 1, 2), PUSHOP(0xd2, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_REG_ECX, SIZE_BYTE, 2), PUSHOP(0xd3, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_REG_ECX, SIZE_BYTE, 2), PUSHOP(0xd4, ADDR_IMMED, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_AAM), PUSHOP(0xd5, ADDR_IMMED, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_AAD), PUSHOP(0xd6, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0xd7, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_XLAT), PUSHOP(0xd8, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xd9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xda, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xdb, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xdc, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xdd, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xde, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xdf, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_FPU), PUSHOP(0xe0, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_LOOPNE), PUSHOP(0xe1, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_LOOPE), PUSHOP(0xe2, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_LOOP), PUSHOP(0xe3, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JECXZ), PUSHOP(0xe4, ADDR_REG_EAX, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, OP_IN), PUSHOP(0xe5, ADDR_REG_EAX, SIZE_WD, ADDR_IMMED, SIZE_BYTE, OP_IN), PUSHOP(0xe6, ADDR_IMMED, SIZE_BYTE, ADDR_REG_EAX, SIZE_BYTE, OP_OUT), PUSHOP(0xe7, ADDR_IMMED, SIZE_BYTE, ADDR_REG_EAX, SIZE_WD, OP_OUT), PUSHOP(0xe8, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CALL), PUSHOP(0xe9, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JMP), PUSHOP(0xea, ADDR_IMMED, SIZE_DF, ADDR_NOADDR, SIZE_NOSIZE, OP_JMP), PUSHOP(0xeb, ADDR_RELJ, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_JMP), PUSHOP(0xec, ADDR_REG_EAX, SIZE_BYTE, ADDR_REG_EDX, SIZE_WORD, OP_IN), PUSHOP(0xed, ADDR_REG_EAX, SIZE_WD, ADDR_REG_EDX, SIZE_WORD, OP_IN), PUSHOP(0xee, ADDR_REG_EDX, SIZE_WORD, ADDR_REG_EAX, SIZE_BYTE, OP_OUT), PUSHOP(0xef, ADDR_REG_EDX, SIZE_WORD, ADDR_REG_EAX, SIZE_WD, OP_OUT), PUSHOP(0xf0, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_LOCK), PUSHOP(0xf1, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0xf2, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_REPNE), PUSHOP(0xf3, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_PREFIX_REPE), PUSHOP(0xf4, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_HLT), PUSHOP(0xf5, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_CMC), PUSHOP(0xf6, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_IMMED, SIZE_BYTE, 6), PUSHOP(0xf7, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMMED, SIZE_WD, 6), PUSHOP(0xf8, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_CLC), PUSHOP(0xf9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_STC), PUSHOP(0xfa, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_CLI), PUSHOP(0xfb, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_STI), PUSHOP(0xfc, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_CLD), PUSHOP(0xfd, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_STD), PUSHOP(0xfe, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 3), PUSHOP(0xff, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, 4), },{ /* 222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 */ PUSHOP(0x00, ADDR_MRM_EXTRA_1A, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, 7), PUSHOP(0x01, ADDR_MRM_EXTRA_1A_M, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 26), /* FIXME: SMSW/LMSW Mw/R[vw] (0f0120,0f0130,660f0120,660f0130,0f01e0,0f01f0,660f01e0,660f01f0) not handled */ PUSHOP(0x02, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LAR), /* FIXME: ssize is always W */ PUSHOP(0x03, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LSL), /* FIXME: ssize is always W */ PUSHOP(0x04, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x05, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_SYSCALL), PUSHOP(0x06, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_CLTS), PUSHOP(0x07, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_SYSRET), PUSHOP(0x08, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVD), PUSHOP(0x09, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_WBINVD), PUSHOP(0x0a, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x0b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UD2), PUSHOP(0x0c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x0d, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x0e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x0f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x10, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x11, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x12, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x13, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x14, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x15, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x16, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x17, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x18, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x19, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x1a, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x1b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x1c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x1d, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x1e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x1f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x20, ADDR_MRM_GEN_RC, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x21, ADDR_MRM_GEN_RD, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x22, ADDR_MRM_GEN_CR, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x23, ADDR_MRM_GEN_DR, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOV), PUSHOP(0x24, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x25, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x26, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x27, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x28, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x29, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x2a, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x2b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x2c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x2d, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x2e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x2f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x30, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_WRMSR), PUSHOP(0x31, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_RDTSC), PUSHOP(0x32, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_RDMSR), PUSHOP(0x33, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_RDPMC), PUSHOP(0x34, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_SYSENTER), PUSHOP(0x35, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_SYSEXIT), PUSHOP(0x36, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x37, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x38, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), /* 3byte escape */ PUSHOP(0x39, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x3a, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), /* 3byte escape */ PUSHOP(0x3b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x3c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x3d, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x3e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x3f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x40, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVO), PUSHOP(0x41, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVNO), PUSHOP(0x42, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVC), PUSHOP(0x43, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVNC), PUSHOP(0x44, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVZ), PUSHOP(0x45, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVNZ), PUSHOP(0x46, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVBE), PUSHOP(0x47, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVA), PUSHOP(0x48, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVS), PUSHOP(0x49, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVNS), PUSHOP(0x4a, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVP), PUSHOP(0x4b, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVNP), PUSHOP(0x4c, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVL), PUSHOP(0x4d, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVGE), PUSHOP(0x4e, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVLE), PUSHOP(0x4f, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMOVG), PUSHOP(0x50, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x51, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x52, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x53, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x54, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x55, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x56, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x57, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x58, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x59, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x5a, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x5b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x5c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x5d, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x5e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x5f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x60, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x61, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x62, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x63, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x64, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x65, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x66, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x67, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x68, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x69, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x6a, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x6b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x6c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x6d, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x6e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x6f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x70, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x71, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x72, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x73, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x74, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x75, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x76, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x77, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x78, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x79, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x7a, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x7b, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0x7c, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x7d, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x7e, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x7f, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0x80, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JO), PUSHOP(0x81, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JNO), PUSHOP(0x82, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JC), PUSHOP(0x83, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JNC), PUSHOP(0x84, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JZ), PUSHOP(0x85, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JNZ), PUSHOP(0x86, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JBE), PUSHOP(0x87, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JA), PUSHOP(0x88, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JS), PUSHOP(0x89, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JNS), PUSHOP(0x8a, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JP), PUSHOP(0x8b, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JNP), PUSHOP(0x8c, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JL), PUSHOP(0x8d, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JGE), PUSHOP(0x8e, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JLE), PUSHOP(0x8f, ADDR_RELJ, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_JG), PUSHOP(0x90, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 8), PUSHOP(0x91, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 9), PUSHOP(0x92, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 10), PUSHOP(0x93, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 11), PUSHOP(0x94, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 12), PUSHOP(0x95, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 13), PUSHOP(0x96, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 14), PUSHOP(0x97, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 15), PUSHOP(0x98, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 16), PUSHOP(0x99, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 17), PUSHOP(0x9a, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 18), PUSHOP(0x9b, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 19), PUSHOP(0x9c, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 20), PUSHOP(0x9d, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 21), PUSHOP(0x9e, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 22), PUSHOP(0x9f, ADDR_MRM_EXTRA_1A, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, 23), PUSHOP(0xa0, ADDR_REG_FS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0xa1, ADDR_REG_FS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0xa2, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_CPUID), PUSHOP(0xa3, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BT), PUSHOP(0xa4, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_IMMED, SIZE_BYTE, OP_SHLD), PUSHOP(0xa5, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_REG_ECX, SIZE_BYTE, OP_SHLD), PUSHOP(0xa6, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0xa7, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0xa8, ADDR_REG_GS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_PUSH), PUSHOP(0xa9, ADDR_REG_GS, SIZE_WORD, ADDR_NOADDR, SIZE_NOSIZE, OP_POP), PUSHOP(0xaa, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_RSM), PUSHOP(0xab, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BTS), PUSHOP(0xac, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_IMMED, SIZE_BYTE, OP_SHRD), PUSHOP(0xad, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_REG_ECX, SIZE_BYTE, OP_SHRD), PUSHOP(0xae, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xaf, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_IMUL), PUSHOP(0xb0, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_CMPXCHG), PUSHOP(0xb1, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_CMPXCHG), PUSHOP(0xb2, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LSS), /* FIXME: mem size is F/D */ PUSHOP(0xb3, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BTR), PUSHOP(0xb4, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LFS), /* FIXME: mem size is F/D */ PUSHOP(0xb5, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LGS), /* FIXME: mem size is F/D */ PUSHOP(0xb6, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVZX), PUSHOP(0xb7, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVZX), PUSHOP(0xb8, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), PUSHOP(0xb9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xba, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMMED, SIZE_BYTE, 24), PUSHOP(0xbb, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BTC), PUSHOP(0xbc, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSF), PUSHOP(0xbd, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSR), PUSHOP(0xbe, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSX), PUSHOP(0xbf, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSX), PUSHOP(0xc0, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_XADD), PUSHOP(0xc1, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_XADD), PUSHOP(0xc2, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xc3, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xc4, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xc5, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xc6, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xc7, ADDR_MRM_EXTRA_1A_M, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, 25), PUSHOP(0xc8, ADDR_REG_EAX, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xc9, ADDR_REG_ECX, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xca, ADDR_REG_EDX, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xcb, ADDR_REG_EBX, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xcc, ADDR_REG_ESP, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xcd, ADDR_REG_EBP, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xce, ADDR_REG_ESI, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xcf, ADDR_REG_EDI, SIZE_DWORD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSWAP), PUSHOP(0xd0, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd1, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd2, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd3, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd4, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd5, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd6, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd7, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd8, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xd9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xda, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xdb, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xdc, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xdd, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xde, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xdf, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe0, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe1, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe2, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe3, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe4, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe5, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe6, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe7, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe8, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xe9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xea, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xeb, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xec, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xed, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xee, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xef, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf0, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf1, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf2, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf3, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf4, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf5, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf6, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf7, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf8, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xf9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xfa, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xfb, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xfc, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xfd, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xfe, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP), PUSHOP(0xff, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID), }}; static const char *dis_size[] = {"byte", "word", "dword", "fword", "qword", "tword", "acab"}; static const char *x86regs[] = { "eax","ecx","edx","ebx","esp","ebp","esi","edi", "ax","cx","dx","bx","sp","bp","si","di", "ah","ch","dh","bh","al","cl","dl","bl", "es","cs","ss","ds","fs","gs", "cr0", "cr1 (rsvd)", "cr2", "cr3", "cr4", "cr5 (rsvd)", "cr6 (rsvd)", "cr7 (rsvd)", "dr0", "dr1", "dr2", "dr3", "dr4 (rsvd)", "dr5 (rsvd)", "dr6", "dr7", "st(0)", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", "" }; static void spam_x86(struct DISASMED *s, char *hr) { int i; char comma[2]={'\0','\0'}; strcpy(hr, mnemonic[s->real_op]); hr += strlen(hr); for (i=0; i<3; i++) { switch(s->args[i].access) { case ACCESS_NOARG: break; case ACCESS_IMM: case ACCESS_REL: if (s->args[i].arg.rq >=0) hr += sprintf(hr, "%s %lx", comma, (long)s->args[i].arg.q); else hr += sprintf(hr, "%s -%x", comma, -(int)s->args[i].arg.rq); break; case ACCESS_REG: hr += sprintf(hr, "%s %s", comma, x86regs[s->args[i].reg]); break; case ACCESS_MEM: { const char *gotstuff=""; hr += sprintf(hr, "%s %s ptr ", comma, dis_size[s->args[i].size]); if(s->segment) hr += sprintf(hr, "%s:", x86regs[s->segment]); *hr++ = '['; *hr = '\0'; if(s->args[i].arg.marg.r1!=X86_REG_INVALID) { switch(s->args[i].arg.marg.scale) { case 1: hr += sprintf(hr, "%s", x86regs[s->args[i].arg.marg.r1]); gotstuff="+"; break; case 0: break; default: hr += sprintf(hr, "%s*%d", x86regs[s->args[i].arg.marg.r1],s->args[i].arg.marg.scale); gotstuff="+"; } } if(s->args[i].arg.marg.r2!=X86_REG_INVALID) { hr += sprintf(hr, "%s%s", gotstuff, x86regs[s->args[i].arg.marg.r2]); gotstuff="+"; } if(s->args[i].arg.marg.disp) { if(*gotstuff=='+' && s->args[i].arg.marg.disp<0) hr += sprintf(hr, "-%x", -s->args[i].arg.marg.disp); else hr += sprintf(hr, "%s%x", gotstuff, s->args[i].arg.marg.disp); } *hr++ = ']'; *hr = '\0'; } } comma[0]=','; } } #define INVALIDATE {s->table_op=OP_INVALID; s->state=STATE_ERROR; goto disasm_failed;} #define GETBYTE(X) if(len--) {X=*command; command++;} else INVALIDATE; #define GETSIZE(X) (x86ops[table][s->table_op].X!=SIZE_WD?x86ops[table][s->table_op].X:((s->opsize)?SIZE_WORD:SIZE_DWORD)) static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struct DISASMED *s) { unsigned int reversed=0, i; uint8_t b; unsigned int table = 0; memset(s, 0, sizeof(struct DISASMED)); s->state = STATE_GETOP; while(1) { switch (s->state) { case STATE_GETOP: GETBYTE(s->table_op); s->real_op=x86ops[table][s->table_op].op; switch(s->real_op) { case OP_FPU: s->state = STATE_DECODEX87; break; case OP_2BYTE: table=1; break; case OP_PREFIX_OPSIZE: s->opsize=1; /* FIXME: check double prefixes */ break; case OP_PREFIX_ADDRSIZE: s->adsize=1; /* FIXME: check double prefixes */ break; case OP_PREFIX_SEGMENT: assert(x86ops[table][s->table_op].dmethod>=ADDR_REG_ES && x86ops[table][s->table_op].dmethod<=ADDR_REG_GS); s->segment = regmap[SIZE_WORD][x86ops[table][s->table_op].dmethod]; break; default: s->state = STATE_CHECKDTYPE; } continue; case STATE_DECODEX87: { uint8_t mod; uint8_t rm; uint8_t rop; uint8_t scale; uint8_t base; uint8_t idx; table = s->table_op - 0xd8; assert(table<8); GETBYTE(rm); if (rm>=0xc0) { /* ST */ rm&=0x3f; if ((s->real_op=x87_st[table][rm].op)==OP_INVALID) INVALIDATE; switch(x87_st[table][rm].args) { case X87_S: reversed = 1; case X87_R: s->args[reversed^1].access = ACCESS_REG; s->args[reversed^1].reg = X86_REG_ST0; case X87_ONE: s->args[reversed].access = ACCESS_REG; s->args[reversed].reg = X86_REG_ST0 + (rm&7); break; case X87_NONE: break; default: assert("Bad data in x87_st"==0); } s->state = STATE_FINALIZE; continue; } /* MRM */ mod=rm>>6; rop=(rm>>3)&7; rm&=7; if ((s->real_op=x87_mrm[table][rop].op)==OP_INVALID) INVALIDATE; s->args[0].size = x87_mrm[table][rop].size; s->args[0].access = ACCESS_MEM; if(!s->adsize) { if (rm==4) { GETBYTE(base); scale=base>>6; idx=(base>>3)&7; base&=7; s->args[0].arg.marg.scale = 1<args[0].arg.marg.r2=mrm_regmap[SIZED][base])==X86_REG_EBP && mod==0) { s->args[0].arg.marg.r2=X86_REG_INVALID; mod=2; } if((s->args[0].arg.marg.r1=mrm_regmap[SIZED][idx])==X86_REG_ESP) { s->args[0].arg.marg.r1=s->args[0].arg.marg.r2; s->args[0].arg.marg.scale = (s->args[0].arg.marg.r2!=X86_REG_INVALID); s->args[0].arg.marg.r2=X86_REG_INVALID; } } else { if (mod==0 && rm==5) { mod=2; s->args[0].arg.marg.r1=X86_REG_INVALID; } else { s->args[0].arg.marg.scale=1; s->args[0].arg.marg.r1=mrm_regmap[SIZED][rm]; } s->args[0].arg.marg.r2=X86_REG_INVALID; } if(mod==2) mod+=mod; for (i=0; iargs[0].arg.marg.disp+=b<<(i*8); /* FIXME: signextend to dword */ } } else { if (mod==0 && rm==6) { s->args[0].arg.marg.r1=X86_REG_INVALID; mod=2; } else { s->args[0].arg.marg.scale=1; s->args[0].arg.marg.r1=mrm_regmapw[rm].r1; s->args[0].arg.marg.r2=mrm_regmapw[rm].r2; } for (i=0; iargs[0].arg.marg.disp+=b<<(i*8); /* FIXME: signextend to dword */ } } s->state = STATE_FINALIZE; break; } case STATE_CHECKDTYPE: switch(x86ops[table][s->table_op].dmethod) { case ADDR_REG_FS: case ADDR_REG_GS: /* FIXME: does this exist? */ case ADDR_REG_ES: case ADDR_REG_CS: case ADDR_REG_SS: case ADDR_REG_DS: assert(x86ops[table][s->table_op].dsize==SIZE_WORD); case ADDR_REG_ESP: case ADDR_REG_EBP: case ADDR_REG_ESI: case ADDR_REG_EDI: assert(x86ops[table][s->table_op].dsize!=SIZE_BYTE && x86ops[table][s->table_op].dsize!=SIZE_BYTEH); case ADDR_REG_EAX: case ADDR_REG_ECX: case ADDR_REG_EDX: case ADDR_REG_EBX: assert(x86ops[table][s->table_op].dsize<=SIZE_WD); s->args[0].access = ACCESS_REG; s->args[0].reg = regmap[GETSIZE(dsize)][x86ops[table][s->table_op].dmethod]; s->state = STATE_CHECKSTYPE; continue; case ADDR_NOADDR: if (x86ops[table][s->table_op].dsize!=SIZE_NOSIZE) { assert(x86ops[table][s->table_op].dsize==SIZE_WD); s->real_op+=(s->opsize!=0); } s->args[0].access = ACCESS_NOARG; s->state = STATE_FINALIZE; continue; case ADDR_RELJ: case ADDR_IMMED: { uint8_t sz; s->args[0].access = x86ops[table][s->table_op].dmethod-ADDR_IMMED+ACCESS_IMM; assert(x86ops[table][s->table_op].dsizeopsize<2); sz=sizemap[x86ops[table][s->table_op].dsize][s->opsize]; assert(sz!=255); s->args[0].size = sz>>1; /* FIXME: size does matter - 6aff vs 666aff :( */ for (i=0; iargs[0].arg.q+=(uint64_t)b<<(i*8); } /* if (x86ops[table][s->table_op].dmethod==ADDR_RELJ) { */ s->args[0].arg.q<<=((8-sz)*8); s->args[0].arg.rq>>=((8-sz)*8); /* } */ s->state = STATE_CHECKSTYPE; continue; } case ADDR_MRM_GEN_GE: case ADDR_MRM_GEN_GM: case ADDR_MRM_GEN_SE: case ADDR_MRM_GEN_CR: case ADDR_MRM_GEN_DR: reversed = 1; case ADDR_MRM_GEN_EG: case ADDR_MRM_GEN_ES: case ADDR_MRM_EXTRA_1A: case ADDR_MRM_EXTRA_1A_M: case ADDR_MRM_GEN_RC: case ADDR_MRM_GEN_RD: { uint8_t mod; uint8_t rm; uint8_t rop; uint8_t scale; uint8_t base; uint8_t idx; int64_t shiftme=0; const uint8_t (*p)[8]; GETBYTE(rm); mod=rm>>6; rop=(rm>>3)&7; rm&=7; switch(x86ops[table][s->table_op].dmethod) { case ADDR_MRM_GEN_RC: case ADDR_MRM_GEN_CR: p = mrm_cregmap; mod = 3; break; case ADDR_MRM_GEN_RD: case ADDR_MRM_GEN_DR: p = mrm_dregmap; mod = 3; break; case ADDR_MRM_GEN_SE: case ADDR_MRM_GEN_ES: p = mrm_sregmap; /* FIXME: CS invalid? */ break; default: p = mrm_regmap; } s->args[reversed].size = SIZEB; switch (x86ops[table][s->table_op].dsize) { case SIZE_DWORD: s->args[reversed].size=SIZED; break; case SIZE_WD: s->args[reversed].size+=(s->opsize==0); case SIZE_WORD: s->args[reversed].size++; case SIZE_BYTE: break; default: assert("Bad size"==0); } s->args[reversed^1].access = ACCESS_REG; if ((s->args[reversed^1].reg = p[s->args[reversed].size][rop]) == X86_REG_INVALID) INVALIDATE; /* MOVZX size fixxup */ if(s->real_op == OP_MOVZX || s->real_op == OP_MOVSX) s->args[reversed].size = SIZEB + (s->table_op & 1); if(mod==3) { if(x86ops[table][s->table_op].dmethod==ADDR_MRM_GEN_GM || x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A_M) INVALIDATE; s->args[reversed].access = ACCESS_REG; s->args[reversed].reg = mrm_regmap[s->args[reversed].size][rm]; if(x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A) { uint8_t opcache = s->real_op; assert(opcache<(sizeof(extra_1a)/sizeof(extra_1a[0][0]))); s->args[0].size+=extra_1a[opcache][rop].addsz; if((s->real_op=extra_1a[opcache][rop].op)==OP_INVALID) INVALIDATE; s->args[1].access=ACCESS_NOARG; if (opcache==6 && rop!=0) { /* f6-f7 - GRP3 - handle test E[bv],I[bv] vs the rest */ s->state = STATE_FINALIZE; continue; } } else s->cur++; s->state = STATE_CHECKSTYPE; continue; } s->args[reversed].access = ACCESS_MEM; if(!s->adsize) { if (rm==4) { GETBYTE(base); scale=base>>6; idx=(base>>3)&7; base&=7; s->args[reversed].arg.marg.scale = 1<args[reversed].arg.marg.r2=mrm_regmap[SIZED][base])==X86_REG_EBP && mod==0) { s->args[reversed].arg.marg.r2=X86_REG_INVALID; mod=2; } if((s->args[reversed].arg.marg.r1=mrm_regmap[SIZED][idx])==X86_REG_ESP) { s->args[reversed].arg.marg.r1=s->args[reversed].arg.marg.r2; s->args[reversed].arg.marg.scale = (s->args[reversed].arg.marg.r2!=X86_REG_INVALID); s->args[reversed].arg.marg.r2=X86_REG_INVALID; } } else { if (mod==0 && rm==5) { mod=2; s->args[reversed].arg.marg.r1=X86_REG_INVALID; } else { s->args[reversed].arg.marg.scale=1; s->args[reversed].arg.marg.r1=mrm_regmap[SIZED][rm]; } s->args[reversed].arg.marg.r2=X86_REG_INVALID; } if(mod==2) mod+=mod; for (i=0; iargs[reversed].arg.marg.disp=shiftme>>((8-mod)*8); } else s->args[reversed].arg.marg.disp=0; } else { if (mod==0 && rm==6) { s->args[reversed].arg.marg.r1=X86_REG_INVALID; mod=2; } else { s->args[reversed].arg.marg.scale=1; s->args[reversed].arg.marg.r1=mrm_regmapw[rm].r1; s->args[reversed].arg.marg.r2=mrm_regmapw[rm].r2; } for (i=0; iargs[reversed].arg.marg.disp=shiftme>>((8-mod)*8); } if(x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A || x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A_M) { uint8_t opcache = s->real_op; assert(opcache<(sizeof(extra_1a)/sizeof(extra_1a[0][0]))); s->args[0].size+=extra_1a[opcache][rop].addsz; if ((s->real_op=extra_1a[opcache][rop].op)==OP_INVALID) INVALIDATE; s->args[1].access=ACCESS_NOARG; if (opcache==6 && rop!=0) { /* f6-f7 - GRP3 - handle test E[bv],I[bv] vs the rest */ s->state = STATE_FINALIZE; continue; } } else s->cur++; s->state = STATE_CHECKSTYPE; continue; } case ADDR_OFFSET: { uint8_t sz; s->args[0].access = ACCESS_MEM; assert((x86ops[table][s->table_op].dsize==SIZE_BYTE || x86ops[table][s->table_op].dsize==SIZE_WD) && s->adsize<2); sz=sizemap[SIZE_WD][s->adsize]; assert(sz!=255); assert(s->opsize<2); s->args[0].size=sizemap[x86ops[table][s->table_op].dsize][s->opsize]; assert(s->args[0].size!=255); s->args[0].size>>=1; s->args[0].arg.marg.r1=X86_REG_INVALID; s->args[0].arg.marg.r2=X86_REG_INVALID; for (i=0; iargs[0].arg.marg.disp+=b<<(i*8); } s->state = STATE_CHECKSTYPE; continue; } default: assert("BAD DST METHOD"==0); } case STATE_CHECKSTYPE: s->cur++; switch(x86ops[table][s->table_op].smethod) { case ADDR_NOADDR: s->state = STATE_FINALIZE; continue; case ADDR_IMMED: { uint8_t sz; s->args[s->cur].access = ACCESS_IMM; assert((x86ops[table][s->table_op].ssize==SIZE_WD || x86ops[table][s->table_op].ssize==SIZE_BYTE) && s->opsize<2); sz=sizemap[x86ops[table][s->table_op].ssize][s->opsize]; s->args[s->cur].size = sz>>1; for (i=0; iargs[s->cur].arg.q+=b<<(i*8); } s->args[s->cur].arg.q<<=((8-sz)*8); s->args[s->cur].arg.rq>>=((8-sz)*8); s->state = STATE_FINALIZE; continue; } case ADDR_REG_EAX: case ADDR_REG_ECX: case ADDR_REG_EDX: assert(x86ops[table][s->table_op].ssize<=SIZE_WD); s->args[s->cur].access = ACCESS_REG; s->args[s->cur].reg = regmap[GETSIZE(ssize)][x86ops[table][s->table_op].smethod]; s->state = STATE_FINALIZE; continue; case ADDR_IMPLICIT: s->args[s->cur].access = ACCESS_IMM; s->args[s->cur].size = 1; s->args[s->cur].arg.q = 1; s->state = STATE_FINALIZE; continue; case ADDR_OFFSET: { uint8_t sz; s->args[1].access = ACCESS_MEM; assert((x86ops[table][s->table_op].ssize==SIZE_BYTE || x86ops[table][s->table_op].ssize==SIZE_WD) && s->adsize<2); sz=sizemap[SIZE_WD][s->adsize]; assert(sz!=255); assert(s->opsize<2); s->args[1].size=sizemap[x86ops[table][s->table_op].ssize][s->opsize]; assert(s->args[1].size!=255); s->args[1].size>>=1; s->args[1].arg.marg.r1=X86_REG_INVALID; s->args[1].arg.marg.r2=X86_REG_INVALID; for (i=0; iargs[1].arg.marg.disp+=b<<(i*8); } s->state = STATE_FINALIZE; continue; } default: assert("BAD SRC METHOD"==0); } case STATE_ERROR: disasm_failed: return NULL; case STATE_FINALIZE: if (s->real_op==OP_INVALID) INVALIDATE; return command; default: assert("INVALID STATE"==0); } } } const uint8_t* cli_disasm_one(const uint8_t* buff, unsigned int len, struct DISASM_RESULT *w, int spam) { struct DISASMED s; int i; memset(&w->extra[0], 0, sizeof(w->extra)); buff = disasm_x86(buff, len, &s); if (!buff) return NULL; if (spam) { char hr[128]; spam_x86(&s, hr); cli_dbgmsg("%s\n", hr); } w->real_op = le16_to_host(s.real_op); w->opsize = s.opsize; w->adsize = s.adsize; w->segment = s.segment; for (i=0; i<3; i++) { w->arg[i][0] = s.args[i].access; w->arg[i][1] = s.args[i].size; switch(s.args[i].access) { case ACCESS_MEM: w->arg[i][2]=s.args[i].arg.marg.r1; w->arg[i][3]=s.args[i].arg.marg.r2; w->arg[i][4]=s.args[i].arg.marg.scale; w->arg[i][5]=0; cli_writeint32(&w->arg[i][6], s.args[i].arg.marg.disp); break; case ACCESS_REG: w->arg[i][1] = s.args[i].reg; default: cli_writeint32(&w->arg[i][2], s.args[i].arg.q); cli_writeint32(&w->arg[i][6], s.args[i].arg.q>>32); } } return buff; } int disasmbuf(const uint8_t *buff, unsigned int len, int fd) { const uint8_t *next = buff; unsigned int counter=0; int gotsome=0; struct DISASM_RESULT w; memset(&w.extra[0], 0, sizeof(w.extra)); while(len && counter++<200) { if(!(next = cli_disasm_one(next, len, &w, cli_debug_flag))) { /* TODO: invd opcode or buff over */ return gotsome; } len -= next-buff; buff=next; cli_writen(fd, &w, sizeof(w)); gotsome = 1; } return gotsome; }