DisasmCore.cpp revision 389b9f89a42b9efcb0d843a6a45c54418dd02e11
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync * VBox disassembler:
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Core components
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Copyright (C) 2006-2007 innotek GmbH
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License as published by the Free Software Foundation,
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Header Files *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/*******************************************************************************
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync* Internal Functions *
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync*******************************************************************************/
efff36b306e370346025647a158689021df2e1d1vboxsyncstatic int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void disasmAddString(char *psz, const char *pszString);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void disasmAddStringF(char *psz, uint32_t cbString, const char *pszFormat, ...);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync# define disasmAddString(psz, pszString) do {} while (0)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync# define disasmAddStringF(psz, cbString, pszFormat...) do {} while (0) /* Arg wanna get rid of that warning */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned QueryModRM(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, int *pSibInc = NULL);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned QueryModRM_SizeOnly(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, int *pSibInc = NULL);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic void UseSIB(RTUINTPTR pu8CodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncstatic unsigned ParseSIB_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Global Variables *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Array for accessing 32-bit general registers in VMMREGFRAME structure
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * by register's index from disasm.
9496f2d398b49813176939d7a339ae513d5175efvboxsyncstatic const unsigned g_aReg32Index[] =
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Macro for accessing 32-bit general purpose registers in CPUMCTXCORE structure.
16a9adc14900ca18e6909679a579f6833425e030vboxsync#define DIS_READ_REG32(p, idx) (*(uint32_t *)((char *)(p) + g_aReg32Index[idx]))
16a9adc14900ca18e6909679a579f6833425e030vboxsync#define DIS_WRITE_REG32(p, idx, val) (*(uint32_t *)((char *)(p) + g_aReg32Index[idx]) = val)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Array for accessing 16-bit general registers in CPUMCTXCORE structure
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * by register's index from disasm.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncstatic const unsigned g_aReg16Index[] =
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Macro for accessing 16-bit general purpose registers in CPUMCTXCORE structure.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#define DIS_READ_REG16(p, idx) (*(uint16_t *)((char *)(p) + g_aReg16Index[idx]))
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#define DIS_WRITE_REG16(p, idx, val) (*(uint16_t *)((char *)(p) + g_aReg16Index[idx]) = val)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Array for accessing 8-bit general registers in CPUMCTXCORE structure
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * by register's index from disasm.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncstatic const unsigned g_aReg8Index[] =
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync RT_OFFSETOF(CPUMCTXCORE, eax) + 1, /* USE_REG_AH */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync RT_OFFSETOF(CPUMCTXCORE, ecx) + 1, /* USE_REG_CH */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync RT_OFFSETOF(CPUMCTXCORE, edx) + 1, /* USE_REG_DH */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Macro for accessing 8-bit general purpose registers in CPUMCTXCORE structure.
16a9adc14900ca18e6909679a579f6833425e030vboxsync#define DIS_READ_REG8(p, idx) (*(uint8_t *)((char *)(p) + g_aReg8Index[idx]))
16a9adc14900ca18e6909679a579f6833425e030vboxsync#define DIS_WRITE_REG8(p, idx, val) (*(uint8_t *)((char *)(p) + g_aReg8Index[idx]) = val)
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Array for accessing segment registers in CPUMCTXCORE structure
16a9adc14900ca18e6909679a579f6833425e030vboxsync * by register's index from disasm.
16a9adc14900ca18e6909679a579f6833425e030vboxsyncstatic const unsigned g_aRegSegIndex[] =
16a9adc14900ca18e6909679a579f6833425e030vboxsyncstatic const unsigned g_aRegHidSegIndex[] =
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Macro for accessing segment registers in CPUMCTXCORE structure.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync#define DIS_READ_REGSEG(p, idx) (*((uint16_t *)((char *)(p) + g_aRegSegIndex[idx])))
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync#define DIS_WRITE_REGSEG(p, idx, val) (*((uint16_t *)((char *)(p) + g_aRegSegIndex[idx])) = val)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Parses one instruction.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * The result is found in pCpu.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * @returns Success indicator.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * @param pCpu Pointer to cpu structure which has DISCPUSTATE::mode set correctly.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * @param InstructionAddr Pointer to the instruction to parse.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * @param pcbInstruction Where to store the size of the instruction.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * NULL is allowed.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncDISDECL(int) DISCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Reset instruction settings
9496f2d398b49813176939d7a339ae513d5175efvboxsync return VBOX_SUCCESS(disCoreOne(pCpu, InstructionAddr, pcbInstruction));
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Parses one guest instruction.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * The result is found in pCpu and pcbInstruction.
9496f2d398b49813176939d7a339ae513d5175efvboxsync * @returns VBox status code.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param InstructionAddr Address of the instruction to decode. What this means
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * is left to the pfnReadBytes function.
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync * @param uCpuMode The CPU mode. CPUMODE_32BIT, CPUMODE_16BIT, or CPUMODE_64BIT.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * @param pfnReadBytes Callback for reading instruction bytes.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param pvUser User argument for the instruction reader. (Ends up in apvUserData[0].)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param pCpu Pointer to cpu structure. Will be initialized.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param pcbInstruction Where to store the size of the instruction.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * NULL is allowed.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsyncDISDECL(int) DISCoreOneEx(RTUINTPTR InstructionAddr, unsigned uCpuMode, PFN_DIS_READBYTES pfnReadBytes, void *pvUser,
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync * Reset instruction settings
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return disCoreOne(pCpu, InstructionAddr, pcbInstruction);
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync * Internal worker for DISCoreOne and DISCoreOneEx.
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync * @returns VBox status code.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param pCpu Initialized cpu state.
ffbe6daf773e38167f3cabaf1f063d84ecd063e9vboxsync * @param InstructionAddr Instruction address.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * @param pcbInstruction Where to store the instruction size. Can be NULL.
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsyncstatic int disCoreOne(PDISCPUSTATE pCpu, RTUINTPTR InstructionAddr, unsigned *pcbInstruction)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Parse byte by byte.
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync unsigned iByte = 0;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync uint8_t codebyte = DISReadByte(pCpu, InstructionAddr+iByte);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync uint8_t opcode = g_aOneByteMapX86[codebyte].opcode;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /* Hardcoded assumption about OP_* values!! */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return VERR_GENERAL_FAILURE; /** @todo better error code. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync // segment override prefix byte
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync pCpu->prefix_seg = g_aOneByteMapX86[codebyte].param1 - OP_PARM_REG_SEG_START;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync continue; //fetch the next byte
16a9adc14900ca18e6909679a579f6833425e030vboxsync // lock prefix byte
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync continue; //fetch the next byte
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync // address size override prefix byte
9496f2d398b49813176939d7a339ae513d5175efvboxsync continue; //fetch the next byte
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync // operand size override prefix byte
9496f2d398b49813176939d7a339ae513d5175efvboxsync continue; //fetch the next byte
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync // rep and repne are not really prefixes, but we'll treat them as such
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync continue; //fetch the next byte
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync continue; //fetch the next byte
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int cbInc = ParseInstruction(InstructionAddr + iByte, &g_aOneByteMapX86[pCpu->opcode], pCpu);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync//*****************************************************************************
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync//*****************************************************************************
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncDISDECL(int) DISGetParamSize(PDISCPUSTATE pCpu, POP_PARAMETER pParam)
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync subtype = (pCpu->opmode == CPUMODE_32BIT) ? OP_PARM_d : OP_PARM_w;
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync else //@todo dangerous!!!
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync//*****************************************************************************
9496f2d398b49813176939d7a339ae513d5175efvboxsync//*****************************************************************************
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsyncDISDECL(int) DISDetectSegReg(PDISCPUSTATE pCpu, POP_PARAMETER pParam)
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync /* Use specified SEG: prefix. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /* Guess segment register by parameter type. */
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync if(pParam->base.reg_gen32 == USE_REG_ESP || pParam->base.reg_gen32 == USE_REG_EBP)
9496f2d398b49813176939d7a339ae513d5175efvboxsync if(pParam->base.reg_gen16 == USE_REG_SP || pParam->base.reg_gen16 == USE_REG_BP)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /* Default is use DS: for data access. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync//*****************************************************************************
9496f2d398b49813176939d7a339ae513d5175efvboxsync//*****************************************************************************
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsyncDISDECL(uint8_t) DISQuerySegPrefixByte(PDISCPUSTATE pCpu)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return 0x26;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return 0x2E;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return 0x36;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return 0x3E;
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync return 0x64;
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync return 0x65;
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync * Returns the value of the specified 8 bits general purpose register
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsyncDISDECL(int) DISFetchReg8(PCPUMCTXCORE pCtx, uint32_t reg8, uint8_t *pVal)
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync AssertReturn(reg8 < ELEMENTS(g_aReg8Index), VERR_INVALID_PARAMETER);
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync * Returns the value of the specified 16 bits general purpose register
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsyncDISDECL(int) DISFetchReg16(PCPUMCTXCORE pCtx, uint32_t reg16, uint16_t *pVal)
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync AssertReturn(reg16 < ELEMENTS(g_aReg16Index), VERR_INVALID_PARAMETER);
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Returns the value of the specified 16 bits general purpose register
16a9adc14900ca18e6909679a579f6833425e030vboxsyncDISDECL(int) DISFetchReg32(PCPUMCTXCORE pCtx, uint32_t reg32, uint32_t *pVal)
16a9adc14900ca18e6909679a579f6833425e030vboxsync AssertReturn(reg32 < ELEMENTS(g_aReg32Index), VERR_INVALID_PARAMETER);
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Returns the value of the specified segment register
16a9adc14900ca18e6909679a579f6833425e030vboxsyncDISDECL(int) DISFetchRegSeg(PCPUMCTXCORE pCtx, uint32_t sel, RTSEL *pVal)
16a9adc14900ca18e6909679a579f6833425e030vboxsync AssertReturn(sel < ELEMENTS(g_aRegSegIndex), VERR_INVALID_PARAMETER);
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Returns the value of the specified segment register including a pointer to the hidden register in the supplied cpu context
16a9adc14900ca18e6909679a579f6833425e030vboxsyncDISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, uint32_t sel, RTSEL *pVal, CPUMSELREGHID **ppSelHidReg)
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync AssertReturn(sel < ELEMENTS(g_aRegSegIndex), VERR_INVALID_PARAMETER);
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync *ppSelHidReg = (CPUMSELREGHID *)((char *)pCtx + g_aRegHidSegIndex[sel]);
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * Updates the value of the specified 32 bits general purpose register
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsyncDISDECL(int) DISWriteReg32(PCPUMCTXCORE pRegFrame, uint32_t reg32, uint32_t val32)
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync AssertReturn(reg32 < ELEMENTS(g_aReg32Index), VERR_INVALID_PARAMETER);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Updates the value of the specified 16 bits general purpose register
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncDISDECL(int) DISWriteReg16(PCPUMCTXCORE pRegFrame, uint32_t reg16, uint16_t val16)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync AssertReturn(reg16 < ELEMENTS(g_aReg16Index), VERR_INVALID_PARAMETER);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Updates the specified 8 bits general purpose register
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncDISDECL(int) DISWriteReg8(PCPUMCTXCORE pRegFrame, uint32_t reg8, uint8_t val8)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync AssertReturn(reg8 < ELEMENTS(g_aReg8Index), VERR_INVALID_PARAMETER);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Updates the specified segment register
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncDISDECL(int) DISWriteRegSeg(PCPUMCTXCORE pCtx, uint32_t sel, RTSEL val)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync AssertReturn(sel < ELEMENTS(g_aRegSegIndex), VERR_INVALID_PARAMETER);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Returns the value of the parameter in pParam
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @returns VBox error code
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param pCtx CPU context structure pointer
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param pCpu Pointer to cpu structure which have DISCPUSTATE::mode
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * set correctly.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param pParam Pointer to the parameter to parse
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param pParamVal Pointer to parameter value (OUT)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param parmtype Parameter type
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @note Currently doesn't handle FPU/XMM/MMX/3DNow! parameters correctly!!
7b067f3f07310bff46d1d6a4ac94d8b9bb7ccccdvboxsyncDISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, POP_PARAMVAL pParamVal, PARAM_TYPE parmtype)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if(pParam->flags & (USE_BASE|USE_INDEX|USE_DISPLACEMENT32|USE_DISPLACEMENT16|USE_DISPLACEMENT8))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync // Effective address
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if(VBOX_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen8, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if(VBOX_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen16, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if(VBOX_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen32, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync // Note that scale implies index (SIB byte)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if(VBOX_FAILURE(DISFetchReg32(pCtx, pParam->index.reg_gen, &val32))) return VERR_INVALID_PARAMETER;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if(pParam->flags & (USE_REG_GEN8|USE_REG_GEN16|USE_REG_GEN32|USE_REG_FP|USE_REG_MMX|USE_REG_XMM|USE_REG_CR|USE_REG_DBG|USE_REG_SEG|USE_REG_TEST))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync // Caller needs to interpret the register according to the instruction (source/target, special value etc)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync //else PARAM_SOURCE
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if(VBOX_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen8, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if(VBOX_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen16, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if(VBOX_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen32, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync // Caller needs to interpret the register according to the instruction (source/target, special value etc)
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if(pParam->flags & (USE_IMMEDIATE8|USE_IMMEDIATE8_REL))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if(pParam->flags & (USE_IMMEDIATE16|USE_IMMEDIATE16_REL|USE_IMMEDIATE_ADDR_0_16|USE_IMMEDIATE16_SX8))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync Assert(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE16_SX8)) );
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if(pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_REL|USE_IMMEDIATE_ADDR_0_32|USE_IMMEDIATE32_SX8))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync Assert(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE32_SX8)) );
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pParamVal->val.farptr.sel = (uint16_t)RT_LOWORD(pParam->parval >> 16);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pParamVal->val.farptr.offset = (uint32_t)RT_LOWORD(pParam->parval);
fe813b3594039ba864493438e78ee0e7132bc445vboxsync pParamVal->size = sizeof(uint16_t) + sizeof(uint32_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pParamVal->val.farptr.sel = (uint16_t)RT_LOWORD(pParam->parval >> 32);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pParamVal->val.farptr.offset = (uint32_t)(pParam->parval & 0xFFFFFFFF);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncunsigned ParseInstruction(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, PDISCPUSTATE pCpu)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync bool fFiltered = false;
fe813b3594039ba864493438e78ee0e7132bc445vboxsync // Store the opcode format string for disasmPrintf
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Apply filter to instruction type to determine if a full disassembly is required.
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync * @note Multibyte opcodes are always marked harmless until the final byte.
16a9adc14900ca18e6909679a579f6833425e030vboxsync /* Not filtered out -> full disassembly */
16a9adc14900ca18e6909679a579f6833425e030vboxsync // Should contain the parameter type on input
16a9adc14900ca18e6909679a579f6833425e030vboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse1](lpszCodeBlock, pOp, &pCpu->param1, pCpu);
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (fFiltered == false) pCpu->param1.size = DISGetParamSize(pCpu, &pCpu->param1);
16a9adc14900ca18e6909679a579f6833425e030vboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse2](lpszCodeBlock+size, pOp, &pCpu->param2, pCpu);
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (fFiltered == false) pCpu->param2.size = DISGetParamSize(pCpu, &pCpu->param2);
16a9adc14900ca18e6909679a579f6833425e030vboxsync size += pCpu->pfnDisasmFnTable[pOp->idxParse3](lpszCodeBlock+size, pOp, &pCpu->param3, pCpu);
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (fFiltered == false) pCpu->param3.size = DISGetParamSize(pCpu, &pCpu->param3);
16a9adc14900ca18e6909679a579f6833425e030vboxsync // else simple one byte instruction
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync/* Floating point opcode parsing */
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseEscFP(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync unsigned size = 0;
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync fpop = &(g_paMapX86_FP_Low[index])[MODRM_REG(pCpu->ModRM)];
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync // Should contain the parameter type on input
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Apply filter to instruction type to determine if a full disassembly is required.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @note Multibyte opcodes are always marked harmless until the final byte.
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync /* Not filtered out -> full disassembly */
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync // Little hack to make sure the ModRM byte is included in the returned size
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync if(fpop->idxParse1 != IDX_ParseModRM && fpop->idxParse2 != IDX_ParseModRM)
fe813b3594039ba864493438e78ee0e7132bc445vboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse1](lpszCodeBlock+size, (PCOPCODE)fpop, pParam, pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync size += pCpu->pfnDisasmFnTable[fpop->idxParse2](lpszCodeBlock+size, (PCOPCODE)fpop, pParam, pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync fpop = &(g_paMapX86_FP_High[index])[pCpu->ModRM - 0xC0];
594521f7faf13f7a88f31e6cd76629bd67340229vboxsync * Apply filter to instruction type to determine if a full disassembly is required.
e04eeee1b306d610b0441cee9bf1c750100254d5vboxsync * @note Multibyte opcodes are always marked harmless until the final byte.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /* Not filtered out -> full disassembly */
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync // Store the opcode format string for disasmPrintf
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync// SIB byte: (32 bits mode only)
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync// 7 - 6 5 - 3 2-0
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync// Scale Index Base
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncconst char *szSIBBaseReg[8] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"};
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsyncconst char *szSIBIndexReg[8] = {"EAX", "ECX", "EDX", "EBX", NULL, "EBP", "ESI", "EDI"};
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync//*****************************************************************************
594521f7faf13f7a88f31e6cd76629bd67340229vboxsyncvoid UseSIB(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
7a3f491705173bc08122f2c7d26d48a8b4c5ceecvboxsync disasmAddStringF(szTemp, sizeof(szTemp), "%s%s", szSIBIndexReg[index], szSIBScale[scale]);
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync disasmAddStringF(szTemp, sizeof(szTemp), "%s+%s%s", szSIBBaseReg[base], szSIBIndexReg[index], szSIBScale[scale]);
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync disasmAddStringF(szTemp, sizeof(szTemp), "%s", szSIBBaseReg[base]);
9496f2d398b49813176939d7a339ae513d5175efvboxsync // [scaled index] + disp32
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync return; /* Already fetched everything in ParseSIB; no size returned */
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync//*****************************************************************************
fe813b3594039ba864493438e78ee0e7132bc445vboxsync//*****************************************************************************
9496f2d398b49813176939d7a339ae513d5175efvboxsyncunsigned ParseSIB(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
fc78e01f665145ab3641c5f8095e9ae984ddcb84vboxsync {//additional 32 bits displacement
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsyncunsigned ParseSIB_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
da3503c04ce76e653401396fe2795a9bc2427a1dvboxsync {//additional 32 bits displacement
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync// ModR/M byte:
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync// 7 - 6 5 - 3 2-0
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync//*****************************************************************************
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncunsigned UseModRM(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "CR%d", reg);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "DR%d", reg);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "MM%d", reg);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "TR%d", reg);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "XMM%d", reg);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "XMM%d", rm);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /* else memory operand */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync //TODO: bound
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync {//32 bits addressing mode
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync case 0: //effective address
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync else {//register address
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {//16 bits addressing mode
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case 0: //effective address
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync {//16 bits displacement
caf54c14752060b187e3fca12a6f71f4b13126b8vboxsync return 0; //everything was already fetched in ParseModRM
68a4ee3a31a0807abd03eae881c1bbaf4d42ee6dvboxsync//*****************************************************************************
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync// Query the size of the ModRM parameters and fetch the immediate data (if any)
9496f2d398b49813176939d7a339ae513d5175efvboxsync//*****************************************************************************
9496f2d398b49813176939d7a339ae513d5175efvboxsyncunsigned QueryModRM(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, int *pSibInc)
548ca31b6b47c36bacce49bed3339cb8075b9681vboxsync unsigned size = 0;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {//32 bits addressing mode
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {//SIB byte follows ModRM
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync *pSibInc = ParseSIB(lpszCodeBlock, pOp, pParam, pCpu);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync case 0: //effective address
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync //else register address
16a9adc14900ca18e6909679a579f6833425e030vboxsync pCpu->disp = (int8_t)DISReadByte(pCpu, lpszCodeBlock);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync size += sizeof(char);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {//16 bits addressing mode
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync case 0: //effective address
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync pCpu->disp = (int8_t)DISReadByte(pCpu, lpszCodeBlock);
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync size += sizeof(char);
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync pCpu->disp = (int16_t)DISReadWord(pCpu, lpszCodeBlock);
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync//*****************************************************************************
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync// Query the size of the ModRM parameters and fetch the immediate data (if any)
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync//*****************************************************************************
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsyncunsigned QueryModRM_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu, int *pSibInc)
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsync unsigned size = 0;
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync {//32 bits addressing mode
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync {//SIB byte follows ModRM
16a9adc14900ca18e6909679a579f6833425e030vboxsync *pSibInc = ParseSIB_SizeOnly(lpszCodeBlock, pOp, pParam, pCpu);
16a9adc14900ca18e6909679a579f6833425e030vboxsync case 0: //effective address
16a9adc14900ca18e6909679a579f6833425e030vboxsync //else register address
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync size += sizeof(char);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {//16 bits addressing mode
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync case 0: //effective address
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync size += sizeof(char);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync//*****************************************************************************
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync//*****************************************************************************
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncunsigned ParseIllegal(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync//*****************************************************************************
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync//*****************************************************************************
efff36b306e370346025647a158689021df2e1d1vboxsyncunsigned ParseModRM(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync size += QueryModRM(lpszCodeBlock, pOp, pParam, pCpu, &sibinc);
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync//*****************************************************************************
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync//*****************************************************************************
27b178e99b06a68ef52353b15bc647674d2006bcvboxsyncunsigned ParseModRM_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync size += QueryModRM_SizeOnly(lpszCodeBlock, pOp, pParam, pCpu, &sibinc);
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync /* UseModRM is not necessary here; we're only interested in the opcode size */
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync//*****************************************************************************
27b178e99b06a68ef52353b15bc647674d2006bcvboxsync//*****************************************************************************
27b178e99b06a68ef52353b15bc647674d2006bcvboxsyncunsigned ParseModFence(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync ////AssertMsgFailed(("??\n"));
16a9adc14900ca18e6909679a579f6833425e030vboxsync //nothing to do apparently
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseImmByte(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%02Xh", (uint32_t)pParam->parval);
16a9adc14900ca18e6909679a579f6833425e030vboxsync return sizeof(uint8_t);
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseImmByte_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync return sizeof(uint8_t);
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
bbede9c189def47a9880f0ffb03c0c230c774185vboxsyncunsigned ParseImmByteSX(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
a3369a746b56a8966dd78619f4d191c9662f400dvboxsync pParam->parval = (uint32_t)(int8_t)DISReadByte(pCpu, lpszCodeBlock);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%08Xh", (uint32_t)pParam->parval);
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync pParam->parval = (uint16_t)(int8_t)DISReadByte(pCpu, lpszCodeBlock);
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04Xh", (uint16_t)pParam->parval);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync return sizeof(uint8_t);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync//*****************************************************************************
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync//*****************************************************************************
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncunsigned ParseImmByteSX_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync return sizeof(uint8_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncunsigned ParseImmUshort(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04Xh", (uint16_t)pParam->parval);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return sizeof(uint16_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
0ccdfa1953b2f57311fb9ec01a2baf5e1e366f5avboxsync//*****************************************************************************
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsyncunsigned ParseImmUshort_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync return sizeof(uint16_t);
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync//*****************************************************************************
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync//*****************************************************************************
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsyncunsigned ParseImmUlong(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync pParam->parval = DISReadDWord(pCpu, lpszCodeBlock);
16a9adc14900ca18e6909679a579f6833425e030vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%08Xh", (uint32_t)pParam->parval);
16a9adc14900ca18e6909679a579f6833425e030vboxsync return sizeof(uint32_t);
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseImmUlong_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync return sizeof(uint32_t);
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseImmQword(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync pParam->parval = DISReadQWord(pCpu, lpszCodeBlock);
16a9adc14900ca18e6909679a579f6833425e030vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%08X", (uint32_t)pParam->parval);
16a9adc14900ca18e6909679a579f6833425e030vboxsync disasmAddStringF(&pParam->szParam[9], sizeof(pParam->szParam)-9, "%08Xh", (uint32_t)(pParam->parval >> 32));
16a9adc14900ca18e6909679a579f6833425e030vboxsync return sizeof(uint64_t);
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseImmQword_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync return sizeof(uint64_t);
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseImmV(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync pParam->parval = DISReadDWord(pCpu, lpszCodeBlock);
16a9adc14900ca18e6909679a579f6833425e030vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%08Xh", (uint32_t)pParam->parval);
670b83d458bceb92123155b5b47a39b9d24e3266vboxsync return sizeof(uint32_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04Xh", (uint32_t)pParam->parval);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return sizeof(uint16_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncunsigned ParseImmV_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
9496f2d398b49813176939d7a339ae513d5175efvboxsync return sizeof(uint32_t);
9496f2d398b49813176939d7a339ae513d5175efvboxsync return sizeof(uint16_t);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync//*****************************************************************************
9496f2d398b49813176939d7a339ae513d5175efvboxsync// Relative displacement for branches (rel. to next instruction)
9496f2d398b49813176939d7a339ae513d5175efvboxsync//*****************************************************************************
b7a5b3f9f9ecce32ddacf8404c625ce0451bbdc1vboxsyncunsigned ParseImmBRel(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
6b223679d40f5e57e55e867e806a9f194e2cde12vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), " (0%02Xh)", (uint32_t)pParam->parval);
d1bffa158f98ff3c18f7d085e7372c9ea00e9a43vboxsync return sizeof(char);
d1bffa158f98ff3c18f7d085e7372c9ea00e9a43vboxsync//*****************************************************************************
6b223679d40f5e57e55e867e806a9f194e2cde12vboxsync// Relative displacement for branches (rel. to next instruction)
6b223679d40f5e57e55e867e806a9f194e2cde12vboxsync//*****************************************************************************
f35c44bfc9e1036d0cb376fb144cdae416c7ef3avboxsyncunsigned ParseImmBRel_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
6b223679d40f5e57e55e867e806a9f194e2cde12vboxsync return sizeof(char);
6b223679d40f5e57e55e867e806a9f194e2cde12vboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync// Relative displacement for branches (rel. to next instruction)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
927320c7f81d3acdbccb5f3fea7548b4b7184b98vboxsyncunsigned ParseImmVRel(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pParam->parval = DISReadDWord(pCpu, lpszCodeBlock);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), " (0%08Xh)", (uint32_t)pParam->parval);
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync return sizeof(int32_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), " (0%04Xh)", (uint32_t)pParam->parval);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return sizeof(uint16_t);
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsync// Relative displacement for branches (rel. to next instruction)
16a9adc14900ca18e6909679a579f6833425e030vboxsync//*****************************************************************************
16a9adc14900ca18e6909679a579f6833425e030vboxsyncunsigned ParseImmVRel_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
16a9adc14900ca18e6909679a579f6833425e030vboxsync return sizeof(int32_t);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return sizeof(uint16_t);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync//*****************************************************************************
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync//*****************************************************************************
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncunsigned ParseImmAddr(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync {// far 16:32 pointer
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync pParam->parval = DISReadDWord(pCpu, lpszCodeBlock);
d9d5fbda1b8f7a6f7fae555db60d0e636fd03af8vboxsync *((uint32_t*)&pParam->parval+1) = DISReadWord(pCpu, lpszCodeBlock+sizeof(uint32_t));
4a23807f02e9920d92c8449bd93d84501add460avboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04X:0%08Xh", (uint32_t)(pParam->parval>>32), (uint32_t)pParam->parval);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {// near 32 bits pointer
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * so we treat it like displacement.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pParam->disp32 = DISReadDWord(pCpu, lpszCodeBlock);
5b465a7c1237993faf8bb50120d247f3f0319adavboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "[0%08Xh]", pParam->disp32);
09127e6ed46502ff8a6a521713ee8ace53667683vboxsync return sizeof(uint32_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {// far 16:16 pointer
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync pParam->parval = DISReadDWord(pCpu, lpszCodeBlock);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "0%04X:0%04Xh", (uint32_t)(pParam->parval>>16), (uint16_t)pParam->parval );
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return sizeof(uint32_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync {// near 16 bits pointer
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync * Note: used only in "mov al|ax|eax, [Addr]" and "mov [Addr], al|ax|eax"
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * so we treat it like displacement.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync disasmAddStringF(pParam->szParam, sizeof(pParam->szParam), "[0%04Xh]", (uint32_t)pParam->disp16);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return sizeof(uint16_t);
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync//*****************************************************************************
8083a259c13e6e26e56ca2582edbad4a8cfac25avboxsync//*****************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsyncunsigned ParseImmAddr_SizeOnly(RTUINTPTR lpszCodeBlock, PCOPCODE pOp, POP_PARAMETER pParam, PDISCPUSTATE pCpu)
9496f2d398b49813176939d7a339ae513d5175efvboxsync {// far 16:32 pointer
cba6719bd64ec749967bbe931230452664109857vboxsync {// near 32 bits pointer
cba6719bd64ec749967bbe931230452664109857vboxsync return sizeof(uint32_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;
if (fRegAddr)
switch(subtype)
case OP_PARM_b:
case OP_PARM_w:
case OP_PARM_d:
#ifdef IN_RING3
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};
#ifdef IN_RING3
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