DisasmCore.cpp revision c5d43ad1264c4b88b4316c42d2abcd16e039d972
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * VBox disassembler:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Core components
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright (C) 2006-2007 Sun Microsystems, Inc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This file is part of VirtualBox Open Source Edition (OSE), as
bff3dadc2c9a6711b6e359fc39d0170de218be50duo liu - Sun Microsystems - Beijing China * available from http://www.virtualbox.org. This file is free software;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * you can redistribute it and/or modify it under the terms of the GNU
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * General Public License (GPL) as published by the Free Software
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Foundation, in version 2 as it comes in the "COPYING" file of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clara, CA 95054 USA or visit http://www.sun.com if you need
bff3dadc2c9a6711b6e359fc39d0170de218be50duo liu - Sun Microsystems - Beijing China * additional information or have any questions.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*******************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte* Header Files *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte*******************************************************************************/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(DIS_CORE_ONLY) && defined(LOG_ENABLED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*******************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte* Internal Functions *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte*******************************************************************************/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(DIS_CORE_ONLY) && defined(LOG_ENABLED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void disasmAddString(char *psz, const char *pszString);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void disasmAddStringF(char *psz, uint32_t cbString, const char *pszFormat, ...);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte# define disasmAddString(psz, pszString) do {} while (0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte# define disasmAddStringF(psz, cbString, pszFormat...) do {} while (0) /* Arg wanna get rid of that warning */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic unsigned QueryModRM(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic unsigned QueryModRM_SizeOnly(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc = NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void UseSIB(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic unsigned ParseSIB_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*******************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte* Global Variables *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte*******************************************************************************/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Parses one instruction.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The result is found in pCpu.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @returns Success indicator.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pCpu Pointer to cpu structure which has DISCPUSTATE::mode set correctly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param InstructionAddr Pointer to the instruction to parse.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pcbInstruction Where to store the size of the instruction.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NULL is allowed.
a79493184c9332129c9c91500069322f6f3fafddReedDISDECL(int) DISCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset instruction settings
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return VBOX_SUCCESS(disCoreOne(pCpu, InstructionAddr, pcbInstruction));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Parses one guest instruction.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The result is found in pCpu and pcbInstruction.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @returns VBox status code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param InstructionAddr Address of the instruction to decode. What this means
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is left to the pfnReadBytes function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param enmCpuMode The CPU mode. CPUMODE_32BIT, CPUMODE_16BIT, or CPUMODE_64BIT.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pfnReadBytes Callback for reading instruction bytes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pvUser User argument for the instruction reader. (Ends up in apvUserData[0].)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pCpu Pointer to cpu structure. Will be initialized.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pcbInstruction Where to store the size of the instruction.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NULL is allowed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteDISDECL(int) DISCoreOneEx(RTUINTPTR InstructionAddr, DISCPUMODE enmCpuMode, PFN_DIS_READBYTES pfnReadBytes, void *pvUser,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Reset instruction settings
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return disCoreOne(pCpu, InstructionAddr, pcbInstruction);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Internal worker for DISCoreOne and DISCoreOneEx.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @returns VBox status code.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pCpu Initialized cpu state.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param InstructionAddr Instruction address.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @param pcbInstruction Where to store the instruction size. Can be NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Parse byte by byte.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned iByte = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t codebyte = DISReadByte(pCpu, InstructionAddr+iByte);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Hardcoded assumption about OP_* values!! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The REX prefix must precede the opcode byte(s). Any other placement is ignored. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /** Last prefix byte (for SSE2 extension tables); don't include the REX prefix */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return VERR_GENERAL_FAILURE; /** @todo better error code. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // segment override prefix byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->prefix_seg = paOneByteMap[codebyte].param1 - OP_PARM_REG_SEG_START;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Segment prefixes for CS, DS, ES and SS are ignored in long mode. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; //fetch the next byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // lock prefix byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; //fetch the next byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // address size override prefix byte
a79493184c9332129c9c91500069322f6f3fafddReed continue; //fetch the next byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // operand size override prefix byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->opmode = CPUMODE_16BIT; /* for 32 and 64 bits mode (there is no 32 bits operand size override prefix) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; //fetch the next byte
a79493184c9332129c9c91500069322f6f3fafddReed // rep and repne are not really prefixes, but we'll treat them as such
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; //fetch the next byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; //fetch the next byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* REX prefix byte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->prefix_rex = PREFIX_REX_OP_2_FLAGS(paOneByteMap[codebyte].param1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->opmode = CPUMODE_64BIT; /* overrides size prefix byte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue; //fetch the next byte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cbInc = ParseInstruction(InstructionAddr + iByte, &paOneByteMap[pCpu->opcode], pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunsigned ParseInstruction(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, PDISCPUSTATE pCpu)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bool fFiltered = false;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // Store the opcode format string for disasmPrintf
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Apply filter to instruction type to determine if a full disassembly is required.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @note Multibyte opcodes are always marked harmless until the final byte.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Not filtered out -> full disassembly */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // Should contain the parameter type on input
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Correct the operand size if the instruction is marked as forced or default 64 bits */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size += pCpu->pfnDisasmFnTable[pOp->idxParse1](lpszCodeBlock, pOp, &pCpu->param1, pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fFiltered == false) pCpu->param1.size = DISGetParamSize(pCpu, &pCpu->param1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size += pCpu->pfnDisasmFnTable[pOp->idxParse2](lpszCodeBlock+size, pOp, &pCpu->param2, pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fFiltered == false) pCpu->param2.size = DISGetParamSize(pCpu, &pCpu->param2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size += pCpu->pfnDisasmFnTable[pOp->idxParse3](lpszCodeBlock+size, pOp, &pCpu->param3, pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fFiltered == false) pCpu->param3.size = DISGetParamSize(pCpu, &pCpu->param3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // else simple one byte instruction
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Floating point opcode parsing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunsigned ParseEscFP(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fpop = &(g_paMapX86_FP_Low[index])[MODRM_REG(ModRM)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // Should contain the parameter type on input
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fpop = &(g_paMapX86_FP_High[index])[ModRM - 0xC0];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Apply filter to instruction type to determine if a full disassembly is required.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @note Multibyte opcodes are always marked harmless until the final byte.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Not filtered out -> full disassembly */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Correct the operand size if the instruction is marked as forced or default 64 bits */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Note: redundant, but just in case this ever changes */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // Little hack to make sure the ModRM byte is included in the returned size
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fpop->idxParse1 != IDX_ParseModRM && fpop->idxParse2 != IDX_ParseModRM)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size += pCpu->pfnDisasmFnTable[fpop->idxParse1](lpszCodeBlock+size, (PCOPCODE)fpop, pParam, pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size += pCpu->pfnDisasmFnTable[fpop->idxParse2](lpszCodeBlock+size, (PCOPCODE)fpop, pParam, pCpu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // Store the opcode format string for disasmPrintf
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
a79493184c9332129c9c91500069322f6f3fafddReed// SIB byte: (32 bits mode only)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// 7 - 6 5 - 3 2-0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Scale Index Base
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const char *szSIBBaseReg[8] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const char *szSIBIndexReg[8] = {"EAX", "ECX", "EDX", "EBX", NULL, "EBP", "ESI", "EDI"};
a79493184c9332129c9c91500069322f6f3fafddReedstatic const char *szSIBBaseReg64[16] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const char *szSIBIndexReg64[16]= {"RAX", "RCX", "RDX", "RBX", NULL, "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic const char *szSIBScale[4] = {"", "*2", "*4", "*8"};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid UseSIB(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(szTemp, sizeof(szTemp), "%s%s", ppszSIBIndexReg[index], szSIBScale[scale]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(szTemp, sizeof(szTemp), "%s+%s%s", ppszSIBBaseReg[base], ppszSIBIndexReg[index], szSIBScale[scale]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(szTemp, sizeof(szTemp), "%s", ppszSIBBaseReg[base]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // [scaled index] + disp32
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return; /* Already fetched everything in ParseSIB; no size returned */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunsigned ParseSIB(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* REX.B extends the Base field if not scaled index + disp32 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(pCpu->SIB.Bits.Base == 5 && pCpu->ModRM.Bits.Mod == 0))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->SIB.Bits.Base |= ((!!(pCpu->prefix_rex & PREFIX_REX_FLAGS_B)) << 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->SIB.Bits.Index |= ((!!(pCpu->prefix_rex & PREFIX_REX_FLAGS_X)) << 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Additional 32 bits displacement. No change in long mode. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunsigned ParseSIB_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* REX.B extends the Base field. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->SIB.Bits.Base |= ((!!(pCpu->prefix_rex & PREFIX_REX_FLAGS_B)) << 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* REX.X extends the Index field. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pCpu->SIB.Bits.Index |= ((!!(pCpu->prefix_rex & PREFIX_REX_FLAGS_X)) << 3);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Additional 32 bits displacement. No change in long mode. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// ModR/M byte:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// 7 - 6 5 - 3 2-0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte//*****************************************************************************
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteunsigned UseModRM(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "CR%d", reg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "DR%d", reg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "MM%d", reg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "TR%d", reg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* memory operand */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte reg = rm; /* the RM field specifies the xmm register */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* else no break */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "XMM%d", reg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* @todo bound */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Assert(pCpu->addrmode == CPUMODE_32BIT || pCpu->addrmode == CPUMODE_64BIT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: displacements in long mode are 8 or 32 bits and sign-extended to 64 bits
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 0: //effective address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { /* SIB byte follows ModRM */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 32 bits displacement */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "RIP+");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {//register address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 1: //effective address + 8 bits displacement
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 2: //effective address + 32 bits displacement
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {//16 bits addressing mode
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 0: //effective address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {//16 bits displacement
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 1: //effective address + 8 bits displacement
unsigned QueryModRM(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
unsigned sibinc;
unsigned size = 0;
if (!pSibInc)
*pSibInc = 0;
switch (mod)
size += sizeof(char);
switch (mod)
size += sizeof(char);
return size;
unsigned QueryModRM_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, unsigned *pSibInc)
unsigned sibinc;
unsigned size = 0;
if (!pSibInc)
*pSibInc = 0;
switch (mod)
size += sizeof(char);
switch (mod)
size += sizeof(char);
return size;
unsigned ParseIllegal(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
AssertFailed();
return size;
unsigned ParseModRM_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseModFence(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned ParseImmByte(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
unsigned ParseImmByte_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
unsigned ParseImmByteSX(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
unsigned ParseImmByteSX_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint8_t);
unsigned ParseImmUshort(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
unsigned ParseImmUshort_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
unsigned ParseImmUlong(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
unsigned ParseImmUlong_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
unsigned ParseImmQword(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
disasmAddStringF(&pParam->szParam[9], sizeof(pParam->szParam)-9, "%08Xh", (uint32_t)(pParam->parval >> 32));
return sizeof(uint64_t);
unsigned ParseImmQword_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint64_t);
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint16_t);
unsigned ParseImmV_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint16_t);
return sizeof(uint16_t);
return sizeof(uint32_t);
unsigned ParseImmZ_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint16_t);
return sizeof(uint32_t);
unsigned ParseImmBRel(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned ParseImmBRel_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned ParseImmVRel(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(int32_t);
return sizeof(int64_t);
return sizeof(uint16_t);
unsigned ParseImmVRel_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(int32_t);
return sizeof(int64_t);
return sizeof(uint16_t);
unsigned ParseImmAddr(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04X:0%08Xh", (uint32_t)(pParam->parval>>32), (uint32_t)pParam->parval);
return sizeof(uint32_t);
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "[0%08X%08Xh]", (uint32_t)(pParam->disp64 >> 32), (uint32_t)pParam->disp64);
return sizeof(uint64_t);
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04X:0%04Xh", (uint32_t)(pParam->parval>>16), (uint16_t)pParam->parval );
return sizeof(uint32_t);
return sizeof(uint16_t);
unsigned ParseImmAddr_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return sizeof(uint32_t);
return sizeof(uint64_t);
return sizeof(uint32_t);
return sizeof(uint16_t);
unsigned ParseFixedReg(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "DS:ESI" : "DS:SI");
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "DS:ESI" : "DS:SI");
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "ES:EDI" : "ES:DI");
disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), (pCpu->addrmode == CPUMODE_32BIT) ? "ES:EDI" : "ES:DI");
unsigned ParseTwoByteEsc(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseNopPause(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
unsigned size = 0;
return size;
unsigned ParseImmGrpl(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
return size;
unsigned ParseShiftGrp2(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
int idx;
return sizeof(uint8_t);
return size;
return size;
return size;
return size;
#ifdef DEBUG_Sander
#ifdef DEBUG_Sander /* bird, 2005-06-28: Alex is getting this during full installation of win2ksp4. */
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
return size;
static const char *szModRMReg8_64[] = {"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8L", "R9L", "R10L", "R11L", "R12L", "R13L", "R14L", "R15L"};
static const char *szModRMReg64[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"};
static const char *szModRMReg1616[8] = {"BX+SI", "BX+DI", "BP+SI", "BP+DI", "SI", "DI", "BP", "BX"};
static const int BaseModRMReg16[8] = { USE_REG_BX, USE_REG_BX, USE_REG_BP, USE_REG_BP, USE_REG_SI, USE_REG_DI, USE_REG_BP, USE_REG_BX};
if (fRegAddr)
case CPUMODE_32BIT:
case CPUMODE_64BIT:
case CPUMODE_16BIT:
switch (subtype)
case OP_PARM_b:
case OP_PARM_w:
case OP_PARM_d:
case OP_PARM_q:
#ifdef IN_RING3
#ifdef IN_RING3
case CPUMODE_32BIT:
case CPUMODE_64BIT:
case CPUMODE_16BIT:
switch (subtype)
case OP_PARM_b:
case OP_PARM_w:
case OP_PARM_d:
case OP_PARM_q:
case OP_PARM_dq:
case OP_PARM_p:
case OP_PARM_s:
case OP_PARM_z:
#ifndef IN_GC
int rc;
return temp;
#ifdef IN_RING0
int rc;
return temp;
#ifdef IN_RING0
int rc;
return temp;
#ifdef IN_RING0
int rc;
return temp;
#ifdef IN_RING0
case OP_BTC:
case OP_BTR:
case OP_BTS:
case OP_CMPXCHG:
case OP_XADD:
case OP_ADC:
case OP_ADD:
case OP_AND:
case OP_DEC:
case OP_INC:
case OP_NEG:
case OP_NOT:
case OP_OR:
case OP_SBB:
case OP_SUB:
case OP_XCHG:
case OP_XOR:
if (pCpu->param1.flags & (USE_BASE | USE_INDEX | USE_DISPLACEMENT32 | USE_DISPLACEMENT16 | USE_DISPLACEMENT8 | USE_RIPDISPLACEMENT32))