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

📄 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 页
字号:
    BOOL op32 = adr32;
    strcpy(mnemonic, opcode->mnemonic);
    strict = TRUE;
    source.code = 0;
    dest.code = 0;

    if (*stream == 0x0f)
    {
        segs |= SG_TWOBYTEOP;
        total_prefixes++;
        stream++;
    }
    if (segs &SG_ADRSIZ)
        adr32 = !adr32;

    if (segs &SG_OPSIZ)
        op32 = !op32;

    if (*stream &1)
    {
        source.flags = 0;
        dest.flags = 0;
    }
    else
    {
        source.flags = OMF_BYTE;
        dest.flags = OMF_BYTE;
    }
    extraoperand.code = 0;

    if (adr32)
    {
        source.flags |= OMF_ADR32;
        dest.flags |= OMF_ADR32;
    }
    if (op32)
    {
        source.flags |= OMF_OP32;
        dest.flags |= OMF_OP32;
    }
    if (opcode->operands)
        stream += (*optable[opcode->operands])(stream, &dest, &source);
    stream += opcode->length;
    return (stream);
}

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

static char *DoStrict(char *buffer, OPERAND *record)
{
    if (strict)
        if (record->flags &OMF_BYTE)
            strcat(buffer, "byte ptr ");
        else
            if (record->flags &OMF_OP32)
                strcat(buffer, "dword ptr ");
            else
                strcat(buffer, "word ptr ");
            else
                if (record->flags &OMF_FSTTAB)
                    sprintf(buffer, "%s ptr ", st[(record->flags >> OM_FTAB)
                        &7]);
    return (buffer + strlen(buffer));
}

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

char *TabTo(char *buffer, int pos)
{
    int temp = pos - strlen(buffer);
    buffer += pos - temp;
    do
    {
        *buffer++ = ' ';
        *buffer = '\0';
    }
    while (--temp > 0);
    return (buffer);
}

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

static char *GetST(char *buffer, OPERAND *record)
{
    sprintf(buffer, "st(%x)", record->reg);
    return (buffer + strlen(buffer));
}

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

static char *GetStdReg(char *buffer, int reg, BOOL use32)
{
    char *pos;

    if (use32)
    {
        *buffer++ = 'e';
        reg |= 8;
    }
    pos = "alcldlblahchdhbhaxcxdxbxspbpsidi" + reg * 2;
    *buffer++ =  *pos++;
    *buffer++ =  *pos;
    *buffer = '\0';
    return (buffer);
}

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

static char *GetReg(char *buffer, OPERAND *record, int reg)
{
    BOOL use32 = ((record->flags &(OMF_OP32 | OMF_BYTE)) == OMF_OP32);
    if (!(record->flags &OMF_BYTE))
        reg |= 8;
    return (GetStdReg(buffer, reg, use32));
}

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

static char *GetSpecial(char *buffer, OPERAND *record, char *name)
{
    *buffer++ =  *name++;
    *buffer++ =  *name++;
    *buffer++ = name[record->reg];
    *buffer = '\0';
    return (buffer);
}

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

static char *GetSeg(char *buffer, int seg, BOOL override)
{
    char *pos = "escsssdsfsgs" + seg * 2;
    *buffer++ =  *pos++;
    *buffer++ =  *pos++;
    if (override)
        *buffer++ = ':';
    *buffer = '\0';
    return (buffer);
}

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

static char *SegOverride(char *buffer)
{
    if (segs &SG_ES)
        buffer = GetSeg(buffer, 0, TRUE);
    if (segs &SG_CS)
        buffer = GetSeg(buffer, 1, TRUE);
    if (segs &SG_SS)
        buffer = GetSeg(buffer, 2, TRUE);
    if (segs &SG_DS)
        buffer = GetSeg(buffer, 3, TRUE);
    if (segs &SG_FS)
        buffer = GetSeg(buffer, 4, TRUE);
    if (segs &SG_GS)
        buffer = GetSeg(buffer, 5, TRUE);
    segs = 0;
    return (buffer);
}

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

static void Scaled(char *buffer, OPERAND *record, BOOL based)
{
    uint flags = record->flags;
    record->flags &= ~OMF_BYTE;
    record->flags |= OMF_OP32;
    if (based)
        buffer = GetStdReg(buffer, record->reg, TRUE);
    if (record->flags &OMF_SCALED)
    {
        char *pos = " + +2*+4*+8*" + record->scale *3;
        *buffer++ =  *pos++;
        *buffer++ =  *pos++;
        *buffer++ =  *pos++;
        buffer = GetStdReg(buffer, record->scalereg, TRUE);
    }
    record->flags = flags;
}

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

static void PutOperand(char *buffer, OPERAND *record)
{
    buffer += strlen(buffer);
    switch (record->code)
    {
        case OM_FSTREG:
            strcat(buffer, "st");
            break;
        case OM_CRX:
            GetSpecial(buffer, record, "CR0?23????");
            break;
        case OM_DRX:
            GetSpecial(buffer, record, "DR0123??67");
            break;
        case OM_TRX:
            GetSpecial(buffer, record, "TR??????67");
            break;
        case OM_SUD:
            GetSpecial(buffer, record, "?R????????");
            break;
        case OM_PORT:
            FormatValue(buffer, record, segs, SY_PORT);
            break;
        case OM_INT:
            FormatValue(buffer, record, segs, SY_INTR);
            break;
        case OM_SHIFT:
            if (record->flags &OMF_CL)
                strcpy(buffer, "cl");
            else
                if (record->address == 1)
                    strcpy(buffer, "1");
                else
                    FormatValue(buffer, record, segs, SY_SHIFT);
            break;
        case OM_RETURN:
            FormatValue(buffer, record, segs, SY_RETURN);
            break;
        case OM_SHORTBRANCH:
            FormatValue(buffer, record, segs, SY_SHORTBRANCH);
            break;
        case OM_LONGBRANCH:
            FormatValue(buffer, record, segs, SY_LONGBRANCH);
            break;
        case OM_FARBRANCH:
            FormatValue(buffer, record, segs, SY_SEGMENT);
            strcat(buffer, ":");
            while (*buffer)
                buffer++;
            FormatValue(buffer, record, segs, SY_ABSBRANCH);
            break;
        case OM_ABSOLUTE:
            buffer = DoStrict(buffer, record);
            buffer = SegOverride(buffer);
            *buffer++ = '[';
            *buffer = '\0';
            if (record->flags &OMF_SCALED)
            {
                FormatValue(buffer, record, segs, SY_WORDOFS);
                while (*buffer)
                    buffer++;
                Scaled(buffer, record, FALSE);
            }
            else
                FormatValue(buffer, record, segs, SY_ABSOLUTE);
            strcat(buffer, "]");
            break;
        case OM_IMMEDIATE:
            if (record->flags &OMF_BYTE)
                if (record->flags &OMF_SIGNED)
                    FormatValue(buffer, record, segs, SY_SIGNEDIMM);
                else
                    FormatValue(buffer, record, segs, SY_BYTEIMM);
                else
                    FormatValue(buffer, record, segs, SY_WORDIMM);
            break;
        case OM_REG:
            if (record->flags &OMF_FST)
                buffer = GetST(buffer, record);
            else
                buffer = GetReg(buffer, record, record->reg);
            break;
        case OM_BASED:
            buffer = DoStrict(buffer, record);
            buffer = SegOverride(buffer);
            *buffer++ = '[';
            *buffer = '\0';
            if (record->flags &OMF_ADR32)
                Scaled(buffer, record, TRUE);
            else
                strcpy(buffer, based[record->reg]);
            while (*buffer)
                buffer++;
            if (record->flags &OMF_OFFSET)
                if (record->flags &OMF_SIGNED_OFFSET)
                    FormatValue(buffer, record, segs, SY_SIGNEDOFS);
                else
                    if (record->flags &OMF_WORD_OFFSET)
                        FormatValue(buffer, record, segs, SY_WORDOFS);
                    else
                        FormatValue(buffer, record, segs, SY_BYTEOFS);
            strcat(buffer, "]");
            break;
        case OM_SEGMENT:
            GetSeg(buffer, record->reg, FALSE);
            break;
    }
}

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

void FormatDissassembly(char *buffer)
{
    char lbuf[256],  *localbuffer = lbuf;
    localbuffer[0] = '\0';
    #ifdef DEBUG
        if (segs &SG_ADRSIZ)
            strcat(localbuffer, "adrsiz: ");
        if (segs &SG_OPSIZ)
            strcat(localbuffer, "opsiz: ");
    #endif /* DEBUG */
    if (segs &SG_REPZ)
        strcat(localbuffer, "repz ");
    if (segs &SG_REPNZ)
        strcat(localbuffer, "repnz ");
    if (segs &SG_REPNC)
        strcat(localbuffer, "repnc ");
    if (segs &SG_REPC)
        strcat(localbuffer, "repc ");
    strcat(localbuffer, mnemonic);
    localbuffer = TabTo(localbuffer, TAB_ARGPOS);

    PutOperand(localbuffer, &dest);
    if (source.code)
    {
        localbuffer += strlen(localbuffer);
        *localbuffer++ = ',';
        *localbuffer = '\0';
        PutOperand(localbuffer, &source);
    }
    if (extraoperand.code)
    {
        localbuffer += strlen(localbuffer);
        *localbuffer++ = ',';
        *localbuffer = '\0';
        PutOperand(localbuffer, &extraoperand);
    }
    buffer[0] = '\0';
    SegOverride(buffer);
    strcat(buffer, lbuf);
}

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

static void RegisterSymbol(OPERAND *record)
{
    record->override = segs;
    switch (record->code)
    {
        case OM_FSTREG:
        case OM_CRX:
        case OM_DRX:
        case OM_TRX:
        case OM_SUD:
            break;
        case OM_PORT:
            AddSymbol(record, SY_PORT);
            break;
        case OM_INT:
            AddSymbol(record, SY_INTR);
            break;
        case OM_SHIFT:
            if ((!record->flags &OMF_CL) && (record->address != 1))
                AddSymbol(record, SY_SHIFT);
            break;
        case OM_RETURN:
            AddSymbol(record, SY_RETURN);
            break;
        case OM_SHORTBRANCH:
            AddSymbol(record, SY_SHORTBRANCH);
            break;
        case OM_LONGBRANCH:
            AddSymbol(record, SY_LONGBRANCH);
            break;
        case OM_FARBRANCH:
            AddSymbol(record, SY_SEGMENT);
            AddSymbol(record, SY_ABSBRANCH);
            break;
        case OM_ABSOLUTE:
            AddSymbol(record, SY_ABSOLUTE);
            break;
        case OM_IMMEDIATE:
            if (record->flags &OMF_BYTE)
                if (record->flags &OMF_SIGNED_OFFSET)
                    AddSymbol(record, SY_SIGNEDIMM);
                else
                    AddSymbol(record, SY_BYTEIMM);
                else
                    AddSymbol(record, SY_WORDIMM);
            break;
        case OM_REG:
            break;
        case OM_BASED:
            if (record->flags &OMF_OFFSET)
                if (record->flags &OMF_SIGNED_OFFSET)
                    AddSymbol(record, SY_SIGNEDOFS);
                else
                    if (record->flags &OMF_WORD_OFFSET)
                        AddSymbol(record, SY_WORDOFS);
                    else
                        AddSymbol(record, SY_BYTEOFS);
            break;
        case OM_SEGMENT:
            break;
    }
}

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

void RegisterSymbols(void)
{
    if (dest.code)
        RegisterSymbol(&dest);
    if (source.code)
        RegisterSymbol(&source);
    if (extraoperand.code)
        RegisterSymbol(&extraoperand);
}

⌨️ 快捷键说明

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