/**
 * Returns the value of the parameter in pParam
 *
 * @returns VBox error code
 * @param   pCtx            CPU context structure pointer
 * @param   pDis            Pointer to the disassembler state.
 * @param   pParam          Pointer to the parameter to parse
 * @param   pParamVal       Pointer to parameter value (OUT)
 * @param   parmtype        Parameter type
 *
 * @note    Currently doesn't handle FPU/XMM/MMX/3DNow! parameters correctly!!
 *
 */
DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PCDISSTATE pDis, PCDISOPPARAM pParam, PDISQPVPARAMVAL pParamVal, DISQPVWHICH parmtype)
{
    memset(pParamVal, 0, sizeof(*pParamVal));

    if (DISUSE_IS_EFFECTIVE_ADDR(pParam->fUse))
    {
        // Effective address
        pParamVal->type = DISQPV_TYPE_ADDRESS;
        pParamVal->size = pParam->cb;

        if (pParam->fUse & DISUSE_BASE)
        {
            if (pParam->fUse & DISUSE_REG_GEN8)
            {
                pParamVal->flags |= DISQPV_FLAG_8;
                if (RT_FAILURE(DISFetchReg8(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
            }
            else
            if (pParam->fUse & DISUSE_REG_GEN16)
            {
                pParamVal->flags |= DISQPV_FLAG_16;
                if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
            }
            else
            if (pParam->fUse & DISUSE_REG_GEN32)
            {
                pParamVal->flags |= DISQPV_FLAG_32;
                if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
            }
            else
            if (pParam->fUse & DISUSE_REG_GEN64)
            {
                pParamVal->flags |= DISQPV_FLAG_64;
                if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER;
            }
            else
            {
                AssertFailed();
                return VERR_INVALID_PARAMETER;
            }
        }
        // Note that scale implies index (SIB byte)
        if (pParam->fUse & DISUSE_INDEX)
        {
            if (pParam->fUse & DISUSE_REG_GEN16)
            {
                uint16_t val16;

                pParamVal->flags |= DISQPV_FLAG_16;
                if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Index.idxGenReg, &val16))) return VERR_INVALID_PARAMETER;

                Assert(!(pParam->fUse & DISUSE_SCALE));   /* shouldn't be possible in 16 bits mode */

                pParamVal->val.val16 += val16;
            }
            else
            if (pParam->fUse & DISUSE_REG_GEN32)
            {
                uint32_t val32;

                pParamVal->flags |= DISQPV_FLAG_32;
                if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Index.idxGenReg, &val32))) return VERR_INVALID_PARAMETER;

                if (pParam->fUse & DISUSE_SCALE)
                    val32 *= pParam->uScale;

                pParamVal->val.val32 += val32;
            }
            else
            if (pParam->fUse & DISUSE_REG_GEN64)
            {
                uint64_t val64;

                pParamVal->flags |= DISQPV_FLAG_64;
                if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Index.idxGenReg, &val64))) return VERR_INVALID_PARAMETER;

                if (pParam->fUse & DISUSE_SCALE)
                    val64 *= pParam->uScale;

                pParamVal->val.val64 += val64;
            }
            else
                AssertFailed();
        }

        if (pParam->fUse & DISUSE_DISPLACEMENT8)
        {
            if (pDis->uCpuMode == DISCPUMODE_32BIT)
                pParamVal->val.val32 += (int32_t)pParam->uDisp.i8;
            else
            if (pDis->uCpuMode == DISCPUMODE_64BIT)
                pParamVal->val.val64 += (int64_t)pParam->uDisp.i8;
            else
                pParamVal->val.val16 += (int16_t)pParam->uDisp.i8;
        }
        else
        if (pParam->fUse & DISUSE_DISPLACEMENT16)
        {
            if (pDis->uCpuMode == DISCPUMODE_32BIT)
                pParamVal->val.val32 += (int32_t)pParam->uDisp.i16;
            else
            if (pDis->uCpuMode == DISCPUMODE_64BIT)
                pParamVal->val.val64 += (int64_t)pParam->uDisp.i16;
            else
                pParamVal->val.val16 += pParam->uDisp.i16;
        }
        else
        if (pParam->fUse & DISUSE_DISPLACEMENT32)
        {
            if (pDis->uCpuMode == DISCPUMODE_32BIT)
                pParamVal->val.val32 += pParam->uDisp.i32;
            else
                pParamVal->val.val64 += pParam->uDisp.i32;
        }
        else
        if (pParam->fUse & DISUSE_DISPLACEMENT64)
        {
            Assert(pDis->uCpuMode == DISCPUMODE_64BIT);
            pParamVal->val.val64 += pParam->uDisp.i64;
        }
        else
        if (pParam->fUse & DISUSE_RIPDISPLACEMENT32)
        {
            Assert(pDis->uCpuMode == DISCPUMODE_64BIT);
            /* Relative to the RIP of the next instruction. */
            pParamVal->val.val64 += pParam->uDisp.i32 + pCtx->rip + pDis->cbInstr;
        }
        return VINF_SUCCESS;
    }

    if (pParam->fUse & (DISUSE_REG_GEN8|DISUSE_REG_GEN16|DISUSE_REG_GEN32|DISUSE_REG_GEN64|DISUSE_REG_FP|DISUSE_REG_MMX|DISUSE_REG_XMM|DISUSE_REG_CR|DISUSE_REG_DBG|DISUSE_REG_SEG|DISUSE_REG_TEST))
    {
        if (parmtype == DISQPVWHICH_DST)
        {
            // Caller needs to interpret the register according to the instruction (source/target, special value etc)
            pParamVal->type = DISQPV_TYPE_REGISTER;
            pParamVal->size = pParam->cb;
            return VINF_SUCCESS;
        }
        //else DISQPVWHICH_SRC

        pParamVal->type = DISQPV_TYPE_IMMEDIATE;

        if (pParam->fUse & DISUSE_REG_GEN8)
        {
            pParamVal->flags |= DISQPV_FLAG_8;
            pParamVal->size   = sizeof(uint8_t);
            if (RT_FAILURE(DISFetchReg8(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
        }
        else
        if (pParam->fUse & DISUSE_REG_GEN16)
        {
            pParamVal->flags |= DISQPV_FLAG_16;
            pParamVal->size   = sizeof(uint16_t);
            if (RT_FAILURE(DISFetchReg16(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
        }
        else
        if (pParam->fUse & DISUSE_REG_GEN32)
        {
            pParamVal->flags |= DISQPV_FLAG_32;
            pParamVal->size   = sizeof(uint32_t);
            if (RT_FAILURE(DISFetchReg32(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
        }
        else
        if (pParam->fUse & DISUSE_REG_GEN64)
        {
            pParamVal->flags |= DISQPV_FLAG_64;
            pParamVal->size   = sizeof(uint64_t);
            if (RT_FAILURE(DISFetchReg64(pCtx, pParam->Base.idxGenReg, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER;
        }
        else
        {
            // Caller needs to interpret the register according to the instruction (source/target, special value etc)
            pParamVal->type = DISQPV_TYPE_REGISTER;
        }
        Assert(!(pParam->fUse & DISUSE_IMMEDIATE));
        return VINF_SUCCESS;
    }

    if (pParam->fUse & DISUSE_IMMEDIATE)
    {
        pParamVal->type = DISQPV_TYPE_IMMEDIATE;
        if (pParam->fUse & (DISUSE_IMMEDIATE8|DISUSE_IMMEDIATE8_REL))
        {
            pParamVal->flags |= DISQPV_FLAG_8;
            if (pParam->cb == 2)
            {
                pParamVal->size   = sizeof(uint16_t);
                pParamVal->val.val16 = (uint8_t)pParam->uValue;
            }
            else
            {
                pParamVal->size   = sizeof(uint8_t);
                pParamVal->val.val8 = (uint8_t)pParam->uValue;
            }
        }
        else
        if (pParam->fUse & (DISUSE_IMMEDIATE16|DISUSE_IMMEDIATE16_REL|DISUSE_IMMEDIATE_ADDR_0_16|DISUSE_IMMEDIATE16_SX8))
        {
            pParamVal->flags |= DISQPV_FLAG_16;
            pParamVal->size   = sizeof(uint16_t);
            pParamVal->val.val16 = (uint16_t)pParam->uValue;
            AssertMsg(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE16_SX8)), ("pParamVal->size %d vs %d EIP=%RX32\n", pParamVal->size, pParam->cb, pCtx->eip) );
        }
        else
        if (pParam->fUse & (DISUSE_IMMEDIATE32|DISUSE_IMMEDIATE32_REL|DISUSE_IMMEDIATE_ADDR_0_32|DISUSE_IMMEDIATE32_SX8))
        {
            pParamVal->flags |= DISQPV_FLAG_32;
            pParamVal->size   = sizeof(uint32_t);
            pParamVal->val.val32 = (uint32_t)pParam->uValue;
            Assert(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE32_SX8)) );
        }
        else
        if (pParam->fUse & (DISUSE_IMMEDIATE64 | DISUSE_IMMEDIATE64_REL | DISUSE_IMMEDIATE64_SX8))
        {
            pParamVal->flags |= DISQPV_FLAG_64;
            pParamVal->size   = sizeof(uint64_t);
            pParamVal->val.val64 = pParam->uValue;
            Assert(pParamVal->size == pParam->cb || ((pParam->cb == 1) && (pParam->fUse & DISUSE_IMMEDIATE64_SX8)) );
        }
        else
        if (pParam->fUse & (DISUSE_IMMEDIATE_ADDR_16_16))
        {
            pParamVal->flags |= DISQPV_FLAG_FARPTR16;
            pParamVal->size   = sizeof(uint16_t)*2;
            pParamVal->val.farptr.sel    = (uint16_t)RT_LOWORD(pParam->uValue >> 16);
            pParamVal->val.farptr.offset = (uint32_t)RT_LOWORD(pParam->uValue);
            Assert(pParamVal->size == pParam->cb);
        }
Exemple #2
0
/**
 * Returns the value of the parameter in pParam
 *
 * @returns VBox error code
 * @param   pCtx            CPU context structure pointer
 * @param   pCpu            Pointer to cpu structure which have DISCPUSTATE::mode
 *                          set correctly.
 * @param   pParam          Pointer to the parameter to parse
 * @param   pParamVal       Pointer to parameter value (OUT)
 * @param   parmtype        Parameter type
 *
 * @note    Currently doesn't handle FPU/XMM/MMX/3DNow! parameters correctly!!
 *
 */
DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PDISCPUSTATE pCpu, POP_PARAMETER pParam, POP_PARAMVAL pParamVal, PARAM_TYPE parmtype)
{
    memset(pParamVal, 0, sizeof(*pParamVal));

    if (DIS_IS_EFFECTIVE_ADDR(pParam->flags))
    {
        // Effective address
        pParamVal->type = PARMTYPE_ADDRESS;
        pParamVal->size = pParam->size;

        if (pParam->flags & USE_BASE)
        {
            if (pParam->flags & USE_REG_GEN8)
            {
                pParamVal->flags |= PARAM_VAL8;
                if (RT_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
            }
            else
            if (pParam->flags & USE_REG_GEN16)
            {
                pParamVal->flags |= PARAM_VAL16;
                if (RT_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
            }
            else
            if (pParam->flags & USE_REG_GEN32)
            {
                pParamVal->flags |= PARAM_VAL32;
                if (RT_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
            }
            else
            if (pParam->flags & USE_REG_GEN64)
            {
                pParamVal->flags |= PARAM_VAL64;
                if (RT_FAILURE(DISFetchReg64(pCtx, pParam->base.reg_gen, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER;
            }
            else
            {
                AssertFailed();
                return VERR_INVALID_PARAMETER;
            }
        }
        // Note that scale implies index (SIB byte)
        if (pParam->flags & USE_INDEX)
        {
            if (pParam->flags & USE_REG_GEN16)
            {
                uint16_t val16;

                pParamVal->flags |= PARAM_VAL16;
                if (RT_FAILURE(DISFetchReg16(pCtx, pParam->index.reg_gen, &val16))) return VERR_INVALID_PARAMETER;

                Assert(!(pParam->flags & USE_SCALE));   /* shouldn't be possible in 16 bits mode */

                pParamVal->val.val16 += val16;
            }
            else
            if (pParam->flags & USE_REG_GEN32)
            {
                uint32_t val32;

                pParamVal->flags |= PARAM_VAL32;
                if (RT_FAILURE(DISFetchReg32(pCtx, pParam->index.reg_gen, &val32))) return VERR_INVALID_PARAMETER;

                if (pParam->flags & USE_SCALE)
                    val32 *= pParam->scale;

                pParamVal->val.val32 += val32;
            }
            else
            if (pParam->flags & USE_REG_GEN64)
            {
                uint64_t val64;

                pParamVal->flags |= PARAM_VAL64;
                if (RT_FAILURE(DISFetchReg64(pCtx, pParam->index.reg_gen, &val64))) return VERR_INVALID_PARAMETER;

                if (pParam->flags & USE_SCALE)
                    val64 *= pParam->scale;

                pParamVal->val.val64 += val64;
            }
            else
                AssertFailed();
        }

        if (pParam->flags & USE_DISPLACEMENT8)
        {
            if (pCpu->mode == CPUMODE_32BIT)
                pParamVal->val.val32 += (int32_t)pParam->disp8;
            else
            if (pCpu->mode == CPUMODE_64BIT)
                pParamVal->val.val64 += (int64_t)pParam->disp8;
            else
                pParamVal->val.val16 += (int16_t)pParam->disp8;
        }
        else
        if (pParam->flags & USE_DISPLACEMENT16)
        {
            if (pCpu->mode == CPUMODE_32BIT)
                pParamVal->val.val32 += (int32_t)pParam->disp16;
            else
            if (pCpu->mode == CPUMODE_64BIT)
                pParamVal->val.val64 += (int64_t)pParam->disp16;
            else
                pParamVal->val.val16 += pParam->disp16;
        }
        else
        if (pParam->flags & USE_DISPLACEMENT32)
        {
            if (pCpu->mode == CPUMODE_32BIT)
                pParamVal->val.val32 += pParam->disp32;
            else
                pParamVal->val.val64 += pParam->disp32;
        }
        else
        if (pParam->flags & USE_DISPLACEMENT64)
        {
            Assert(pCpu->mode == CPUMODE_64BIT);
            pParamVal->val.val64 += (int64_t)pParam->disp64;
        }
        else
        if (pParam->flags & USE_RIPDISPLACEMENT32)
        {
            Assert(pCpu->mode == CPUMODE_64BIT);
            /* Relative to the RIP of the next instruction. */
            pParamVal->val.val64 += pParam->disp32 + pCtx->rip + pCpu->opsize;
        }
        return VINF_SUCCESS;
    }

    if (pParam->flags & (USE_REG_GEN8|USE_REG_GEN16|USE_REG_GEN32|USE_REG_GEN64|USE_REG_FP|USE_REG_MMX|USE_REG_XMM|USE_REG_CR|USE_REG_DBG|USE_REG_SEG|USE_REG_TEST))
    {
        if (parmtype == PARAM_DEST)
        {
            // Caller needs to interpret the register according to the instruction (source/target, special value etc)
            pParamVal->type = PARMTYPE_REGISTER;
            pParamVal->size = pParam->size;
            return VINF_SUCCESS;
        }
        //else PARAM_SOURCE

        pParamVal->type = PARMTYPE_IMMEDIATE;

        if (pParam->flags & USE_REG_GEN8)
        {
            pParamVal->flags |= PARAM_VAL8;
            pParamVal->size   = sizeof(uint8_t);
            if (RT_FAILURE(DISFetchReg8(pCtx, pParam->base.reg_gen, &pParamVal->val.val8))) return VERR_INVALID_PARAMETER;
        }
        else
        if (pParam->flags & USE_REG_GEN16)
        {
            pParamVal->flags |= PARAM_VAL16;
            pParamVal->size   = sizeof(uint16_t);
            if (RT_FAILURE(DISFetchReg16(pCtx, pParam->base.reg_gen, &pParamVal->val.val16))) return VERR_INVALID_PARAMETER;
        }
        else
        if (pParam->flags & USE_REG_GEN32)
        {
            pParamVal->flags |= PARAM_VAL32;
            pParamVal->size   = sizeof(uint32_t);
            if (RT_FAILURE(DISFetchReg32(pCtx, pParam->base.reg_gen, &pParamVal->val.val32))) return VERR_INVALID_PARAMETER;
        }
        else
        if (pParam->flags & USE_REG_GEN64)
        {
            pParamVal->flags |= PARAM_VAL64;
            pParamVal->size   = sizeof(uint64_t);
            if (RT_FAILURE(DISFetchReg64(pCtx, pParam->base.reg_gen, &pParamVal->val.val64))) return VERR_INVALID_PARAMETER;
        }
        else
        {
            // Caller needs to interpret the register according to the instruction (source/target, special value etc)
            pParamVal->type = PARMTYPE_REGISTER;
        }
        Assert(!(pParam->flags & USE_IMMEDIATE));
        return VINF_SUCCESS;
    }

    if (pParam->flags & USE_IMMEDIATE)
    {
        pParamVal->type = PARMTYPE_IMMEDIATE;
        if (pParam->flags & (USE_IMMEDIATE8|USE_IMMEDIATE8_REL))
        {
            pParamVal->flags |= PARAM_VAL8;
            if (pParam->size == 2)
            {
                pParamVal->size   = sizeof(uint16_t);
                pParamVal->val.val16 = (uint8_t)pParam->parval;
            }
            else
            {
                pParamVal->size   = sizeof(uint8_t);
                pParamVal->val.val8 = (uint8_t)pParam->parval;
            }
        }
        else
        if (pParam->flags & (USE_IMMEDIATE16|USE_IMMEDIATE16_REL|USE_IMMEDIATE_ADDR_0_16|USE_IMMEDIATE16_SX8))
        {
            pParamVal->flags |= PARAM_VAL16;
            pParamVal->size   = sizeof(uint16_t);
            pParamVal->val.val16 = (uint16_t)pParam->parval;
            AssertMsg(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE16_SX8)), ("pParamVal->size %d vs %d EIP=%RX32\n", pParamVal->size, pParam->size, pCtx->eip) );
        }
        else
        if (pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_REL|USE_IMMEDIATE_ADDR_0_32|USE_IMMEDIATE32_SX8))
        {
            pParamVal->flags |= PARAM_VAL32;
            pParamVal->size   = sizeof(uint32_t);
            pParamVal->val.val32 = (uint32_t)pParam->parval;
            Assert(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE32_SX8)) );
        }
        else
        if (pParam->flags & (USE_IMMEDIATE64 | USE_IMMEDIATE64_REL | USE_IMMEDIATE64_SX8))
        {
            pParamVal->flags |= PARAM_VAL64;
            pParamVal->size   = sizeof(uint64_t);
            pParamVal->val.val64 = pParam->parval;
            Assert(pParamVal->size == pParam->size || ((pParam->size == 1) && (pParam->flags & USE_IMMEDIATE64_SX8)) );
        }
        else
        if (pParam->flags & (USE_IMMEDIATE_ADDR_16_16))
        {
            pParamVal->flags |= PARAM_VALFARPTR16;
            pParamVal->size   = sizeof(uint16_t)*2;
            pParamVal->val.farptr.sel    = (uint16_t)RT_LOWORD(pParam->parval >> 16);
            pParamVal->val.farptr.offset = (uint32_t)RT_LOWORD(pParam->parval);
            Assert(pParamVal->size == pParam->size);
        }
Exemple #3
0
/**
 * Returns the contents of register or immediate data of instruction's parameter.
 *
 * @returns true on success.
 *
 * @todo Get rid of this code. Use DISQueryParamVal instead
 *
 * @param   pCpu                Pointer to current disassembler context.
 * @param   pParam              Pointer to parameter of instruction to process.
 * @param   pRegFrame           Pointer to CPUMCTXCORE guest structure.
 * @param   pu64Data            Where to store retrieved data.
 * @param   pcbSize             Where to store the size of data (1, 2, 4, 8).
 */
bool iomGetRegImmData(PDISCPUSTATE pCpu, PCDISOPPARAM pParam, PCPUMCTXCORE pRegFrame, uint64_t *pu64Data, unsigned *pcbSize)
{
    NOREF(pCpu);
    if (pParam->fUse & (DISUSE_BASE | DISUSE_INDEX | DISUSE_SCALE | DISUSE_DISPLACEMENT8 | DISUSE_DISPLACEMENT16 | DISUSE_DISPLACEMENT32))
    {
        *pcbSize  = 0;
        *pu64Data = 0;
        return false;
    }

    /* divide and conquer */
    if (pParam->fUse & (DISUSE_REG_GEN64 | DISUSE_REG_GEN32 | DISUSE_REG_GEN16 | DISUSE_REG_GEN8))
    {
        if (pParam->fUse & DISUSE_REG_GEN32)
        {
            *pcbSize  = 4;
            DISFetchReg32(pRegFrame, pParam->Base.idxGenReg, (uint32_t *)pu64Data);
            return true;
        }

        if (pParam->fUse & DISUSE_REG_GEN16)
        {
            *pcbSize  = 2;
            DISFetchReg16(pRegFrame, pParam->Base.idxGenReg, (uint16_t *)pu64Data);
            return true;
        }

        if (pParam->fUse & DISUSE_REG_GEN8)
        {
            *pcbSize  = 1;
            DISFetchReg8(pRegFrame, pParam->Base.idxGenReg, (uint8_t *)pu64Data);
            return true;
        }

        Assert(pParam->fUse & DISUSE_REG_GEN64);
        *pcbSize  = 8;
        DISFetchReg64(pRegFrame, pParam->Base.idxGenReg, pu64Data);
        return true;
    }
    else
    {
        if (pParam->fUse & (DISUSE_IMMEDIATE64 | DISUSE_IMMEDIATE64_SX8))
        {
            *pcbSize  = 8;
            *pu64Data = pParam->uValue;
            return true;
        }

        if (pParam->fUse & (DISUSE_IMMEDIATE32 | DISUSE_IMMEDIATE32_SX8))
        {
            *pcbSize  = 4;
            *pu64Data = (uint32_t)pParam->uValue;
            return true;
        }

        if (pParam->fUse & (DISUSE_IMMEDIATE16 | DISUSE_IMMEDIATE16_SX8))
        {
            *pcbSize  = 2;
            *pu64Data = (uint16_t)pParam->uValue;
            return true;
        }

        if (pParam->fUse & DISUSE_IMMEDIATE8)
        {
            *pcbSize  = 1;
            *pu64Data = (uint8_t)pParam->uValue;
            return true;
        }

        if (pParam->fUse & DISUSE_REG_SEG)
        {
            *pcbSize  = 2;
            DISFetchRegSeg(pRegFrame, (DISSELREG)pParam->Base.idxSegReg, (RTSEL *)pu64Data);
            return true;
        } /* Else - error. */

        AssertFailed();
        *pcbSize  = 0;
        *pu64Data = 0;
        return false;
    }
}