⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 operands.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
        dest->address = UINT(stream + 1);
    dest->segment = UINT(stream + ofs + 3);
    return (ofs);
}

/* op 19 - ESC, mnem of bits 0-2 of opcode, imm,readrm */
static uint OP19(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    dest->code = OM_IMMEDIATE;
    dest->flags |= OMF_BYTE;
    dest->address = ((*(stream) &7) << 3) + ((*(stream + 1) >> 3) &7);

    /* Note that byte mode and ESC code use the same bit... */
    return (ReadRM(stream, source));
}

/* op 20 - long branch */
static uint OP20(BYTE *stream, OPERAND *dest)
{
    strict = FALSE;
    dest->code = OM_LONGBRANCH;
    if (dest->flags &OMF_OP32)
    {
        dest->address = code_address + LONG(stream + 1) + 5+total_prefixes;
        return (2);
    }
    else
    {
        dest->address = code_address + UINT(stream + 1) + 3+total_prefixes;
        dest->address = dest->address &0xffff;
    }
    return (0);
}

/* op21 acc,dx */
static uint OP21(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    stream++;
    SetReg(dest, REG_eAX);
    source->flags &= ~(OMF_OP32 | OMF_BYTE);
    SetReg(source, REG_DX);
    return (0);
}

/* op22 - dx,acc */
static uint OP22(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    stream++;
    dest->flags &= ~(OMF_OP32 | OMF_BYTE);
    SetReg(dest, REG_DX);
    SetReg(source, REG_eAX);
    return (0);
}

/* op23 - port,acc where B1 of opcode set is port dest */
static uint OP23(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    if (B1(*stream))
    {
        dest->flags |= OMF_BYTE;
        dest->code = OM_PORT;
        dest->address = *(stream + 1);
        SetReg(source, REG_eAX);
    }
    else
    {
        SetReg(dest, REG_eAX);
        source->flags |= OMF_BYTE;
        source->code = OM_PORT;
        source->address = *(stream + 1);
    }

    return (0);
}

/* op 24 acc, absolute */
static uint OP24(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    int ofs = 0;
    SetReg(dest, REG_eAX);
    source->code = OM_ABSOLUTE;
    if (source->flags &OMF_ADR32)
    {
        source->address = LONG(stream + 1);
        ofs += 2;
    }
    else
        source->address = UINT(stream + 1);
    return (ofs);
}

/* op 25 - immediate byte or word */
static uint OP25(BYTE *stream, OPERAND *dest)
{
    strict = FALSE;
    if (B1(*stream))
        dest->flags |= OMF_BYTE;
    else
        dest->flags &= ~OMF_BYTE;

    return (Immediate(stream + 1, dest));
}

/* op 26, immediate 2byte,byte */
static uint OP26(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    strict = FALSE;
    dest->flags &= ~(OMF_BYTE | OMF_OP32);
    Immediate(stream + 1, dest);
    source->flags |= OMF_BYTE;
    source->flags &= ~OMF_OP32;
    Immediate(stream + 3, source);
    return (0);
}

/* op 27 - string */
static uint OP27(BYTE *stream, OPERAND *dest)
{
    stream++;
    if (segs &SG_OPSIZ)
        if (dest->flags &OMF_OP32)
            MnemonicChar('d');
        else
            MnemonicChar('w');

    return (0);
}

/* op 28 - source = REG, dest = RM */
static uint OP28(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    SetReg(dest, REG(stream));
    SetReg(source, RM(stream));
    return (0);
}

/* op 29 - dest = RM, immediate */
static uint OP29(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    dest->flags |= OMF_BYTE;
    SetReg(dest, RM(stream));
    source->flags |= OMF_BYTE;
    Immediate(stream + 2, source);
    return (0);
}

/* op30 - RM, shift with B3 of stream selecting COUNT or CL*/
static uint OP30(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    int ofs = ReadRM(stream, dest);

    source->code = OM_SHIFT;
    if (B3(*stream))
    /* The original author didn't let the RM field have any offsets... */
        source->address = *(stream + (ofs++) + 2);
    else
        source->flags |= OMF_CL;

    return (ofs);
}

/* op 31- reg, rm, count wher B1 of opcode = byte/word */
static uint OP31(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    int ofs;
    extraoperand =  *dest;

    SetReg(dest, REG(stream));

    ofs = ReadRM(stream, source);
    if (B1(*stream))
        extraoperand.flags |= OMF_BYTE;
    else
        extraoperand.flags &= ~OMF_BYTE;

    ofs += Immediate(stream + 2, &extraoperand);
    return (ofs);
}

/* op32 - 386 special regs */
static uint OP32(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    uint id = *((uint*)(stream)) &0xc005;
    if (id == 0xc000)
        id = OM_CRX;
    else
        if (id == 0xc001)
            id = OM_DRX;
        else
            if (id == 0xc004)
                id = OM_TRX;
            else
                id = OM_SUD;

    dest->flags &= ~OMF_BYTE;
    source->flags &= ~OMF_BYTE;
    source->flags |= OMF_OP32;
    dest->flags |= OMF_OP32;
    if (B1(*stream))
    {
        dest->code = id;
        dest->reg = REG(stream);
        SetReg(source, RM(stream));
    }
    else
    {
        SetReg(dest, RM(stream));
        source->code = id;
        source->reg = REG(stream);
    }
    return (0);
}

/* op33 - reg,rm,shiftcnt where B3 = reg source, b0 = shift cl */
static uint OP33(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    int ofs;
    dest->flags &= ~OMF_BYTE;
    source->flags &= ~OMF_BYTE;
    extraoperand =  *dest;
    extraoperand.code |= OM_SHIFT;
    ofs = ReadRM(stream, dest);
    SetReg(source, REG(stream));
    if (B0(*stream))
        extraoperand.flags |= OMF_CL;
    else
        extraoperand.address = *(stream + 2+ofs);

    return (ofs);
}

/* op 34 - push & pop word */
static uint OP34(BYTE *stream, OPERAND *dest)
{
    if ((segs &SG_TWOBYTEOP) || !(segs &SG_OPSIZ))
        strict = FALSE;
    return (ReadRM(stream, dest));
}

/* op 35 -floating RM */
static uint OP35(BYTE *stream, OPERAND *dest)
{
    strict = FALSE;
    if ((*((uint*)stream) &0xd0de) == 0xd0de)
        MnemonicChar('p');
    if (MOD(stream) != 3)
        dest->flags |= OMF_FSTTAB | (B12(*stream) << OM_FTAB);
    else
        dest->flags |= OMF_FST;
    return (ReadRM(stream, dest));
}

/* op 36 - sized floating RM */
static uint OP36(BYTE *stream, OPERAND *dest)
{
    int size = SZ_QWORD;
    strict = FALSE;

    if ((*((uint*)stream) &0x2807) != 0x2807)
        size = SZ_TBYTE;

    dest->flags |= OMF_FSTTAB | ((size) << OM_FTAB);
    return (ReadRM(stream, dest));
}

/* OP 37 - floating MATH */
static uint OP37(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    int ofs = 0, flop = 0;
    strict = FALSE;
    if ((*((uint*)stream) &0xc0de) == 0xc0de)
        flop = 1;
    if (((REG(stream) &5) ^ flop) == 5)
        MnemonicChar('r');

    if (MOD(stream) != 3)
    {
        ofs = ReadRM(stream, dest);
        dest->flags |= OMF_FSTTAB | (B12(*stream) << OM_FTAB);
    }
    else
    {
        if (*stream &6)
            MnemonicChar('p');
        if (*stream &4)
        {
            SetReg(dest, RM(stream));
            dest->flags |= OMF_FST;
            source->code = OM_FSTREG;
        }
        else
        {
            dest->code = OM_FSTREG;
            SetReg(source, RM(stream));
            source->flags |= OMF_FST;
        }
    }
    return (ofs);
}

//-------------------------------------------------------------------------

static uint OP38(BYTE *stream, OPERAND *dest)
{
    /* This is how we get a DWORD PTR for the far jump */
    strict = FALSE;
    dest->flags |= OMF_FSTTAB;
    return (ReadRM(stream, dest));
}

/* OP39 - word regrm with reg source */
static uint OP39(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    dest->flags &= ~OMF_BYTE;
    source->flags &= ~OMF_BYTE;
    return (RegRM(stream, source, dest));
}

/* op 40 regrm with reg source */
static uint OP40(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    return (RegRM(stream, source, dest));
}

/* op 41 reg, bitnum */
static uint OP41(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    int ofs;
    dest->flags &= ~OMF_BYTE;
    ofs = ReadRM(stream, dest);
    source->flags |= OMF_BYTE;
    Immediate(stream + 2+ofs, source);
    return (ofs);
}

/* op 42 mixed regrm with reg dest & strictness enforced */
static uint OP42(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    int ofs = RegRM(stream, dest, source);
    dest->flags &= ~OMF_BYTE;
    source->flags &= ~OMF_OP32;
    strict = TRUE;
    return (ofs);
}

/* op43 - REGRM with b0 of opcode set reg is word else byte */
static uint OP43(BYTE *stream, OPERAND *dest, OPERAND *source)
{
    if (!B0(*stream))
    {
        dest->flags |= OMF_BYTE;
        source->flags |= OMF_BYTE;
    }
    return (RegRM(stream, dest, source)); /* Reg is dest */
}

//-------------------------------------------------------------------------

static FUNC optable[44] = 
{
    0, OP1, OP2, OP3, OP4, OP5, OP6, OP7, OP8, OP9, OP10, OP11, OP12, OP13,
        OP14, OP15, OP16, OP17, OP18, OP19, OP20, OP21, OP22, OP23, OP24, OP25,
        OP26, OP27, OP28, OP29, OP30, OP31, OP32, OP33, OP34, OP35, OP36, OP37,
        OP38, OP39, OP40, OP41, OP42, OP43
};

BYTE *ReadOverrides(BYTE *stream, uint validator)
{
    segs = 0;
    total_prefixes = 0;

    for (;; stream++)
    {
        if (validator &VAL_VX)
        {
            if ((uint)(*stream - 0x64) < 2)
            {
                segs |= SG_REPNC << (*stream - 0x64);
                total_prefixes++;
                continue;
            }
        }
        if (validator &VAL_386)
        {
            if ((uint)(*stream - 0x64) < 4)
            {
                segs |= SG_FS << (*stream - 0x64);
                total_prefixes++;
                continue;
            }
        }
        if ((*stream &0xe7) == 0x26)
        {
            segs |= 1 << ((*stream >> 3) &3);
            total_prefixes++;
            continue;
        }
        if ((uint)(*stream - 0xf2) < 2)
        {
            segs |= SG_REPNZ << (*stream - 0xf2);
            total_prefixes++;
            continue;
        }
        break;
    }
    return (stream);
}

//-------------------------------------------------------------------------

BYTE *DispatchOperand(BYTE *stream, OPTABLE *opcode, BOOL adr32)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -