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

📄 inasm386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (!ap1)
        return 0;
    if (isrm(ap1, FALSE))
    {
        if (ap1->length != 7 && ap1->length != 8)
            return (OCODE*) - 2;
    }
    else
    {
        if (ap1->mode != am_freg)
            return (OCODE*) - 1;
        if (lastst == comma)
        {
            getsym();
            ap2 = asm_amode(TRUE);
            if (ap2->mode != am_freg)
                return (OCODE*) - 1;
            if (ap1->preg && ap2->preg)
                return (OCODE*) - 1;
        }
    }
    return make_ocode(ap1, ap2, 0);
}

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

static OCODE *ope_fmathp(void)
{
    AMODE *ap1,  *ap2 = 0;
    if (lastst != kw_asmreg)
        return make_ocode(0, 0, 0);
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_freg)
        return (OCODE*) - 1;
    if (lastst == comma)
    {
        getsym();
        ap2 = asm_amode(TRUE);
        if (!ap2)
            return 0;
        if (ap2->mode != am_freg)
            return (OCODE*) - 1;
        if (ap1->preg && ap2->preg)
            return (OCODE*) - 1;
    }
    return make_ocode(ap1, ap2, 0);
}

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

static OCODE *ope_fmathi(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (isrm(ap1, FALSE))
    {
        if (ap1->length != 7 && ap1->length != 2 && ap1->length != 8)
            return (OCODE*) - 2;
    }
    else
    {
        return (OCODE*) - 1;
    }
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_fcom(void)
{
    AMODE *ap1;
    if (lastst != kw_asmreg)
        return make_ocode(0, 0, 0);
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (isrm(ap1, FALSE))
    {
        if (ap1->length != 7 && ap1->length != 8)
            return (OCODE*) - 2;
    }
    else
    {
        if (ap1->mode != am_freg)
            return (OCODE*) - 1;
    }
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_freg(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_freg)
        return (OCODE*) - 1;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_ficom(void)
{
    AMODE *ap1,  *ap2;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (!isrm(ap1, FALSE))
        return (OCODE*) - 1;
    if (ap1->length != 2 && ap1->length != 7 && ap1->length != 8)
        return (OCODE*) - 2;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_fild(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (!isrm(ap1, FALSE))
        return (OCODE*) - 1;
    if (ap1->length != 2 && ap1->length != 7 && ap1->length != 8)
        return (OCODE*) - 2;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_fist(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (!isrm(ap1, FALSE))
        return (OCODE*) - 1;
    if (ap1->length != 2 && ap1->length != 7)
        return (OCODE*) - 2;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_fld(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (isrm(ap1, FALSE))
    {
        if (ap1->length != 7 && ap1->length != 8 && ap1->length != 10)
            return (OCODE*) - 2;
    }
    else if (ap1->mode != am_freg)
        return (OCODE*) - 1;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_fst(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (isrm(ap1, FALSE))
    {
        if (ap1->length != 7 && ap1->length != 8)
            return (OCODE*) - 2;
    }
    else if (ap1->mode != am_freg || ap1->preg == 0)
        return (OCODE*) - 1;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_fstp(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (isrm(ap1, FALSE))
    {
        if (ap1->length != 7 && ap1->length != 8 && ap1->length != 10)
            return (OCODE*) - 2;
    }
    else if (ap1->mode != am_freg || ap1->preg == 0)
        return (OCODE*) - 1;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_fucom(void)
{
    AMODE *ap1;
    if (lastst != kw_asmreg)
        return make_ocode(0, 0, 0);
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_freg || ap1->preg == 0)
        return (OCODE*) - 1;
    return make_ocode(ap1, 0, 0);

}

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

static OCODE *ope_fxch(void)
{
    return ope_fucom();
}

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

static OCODE *ope_mn(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (!isrm(ap1, FALSE))
        return (OCODE*) - 1;
    ap1->length = 0;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_m16(void)
{
    AMODE *ap1;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (!isrm(ap1, TRUE))
        return (OCODE*) - 1;
    if (ap1->mode == am_dreg)
        if (op != op_fstsw && op != op_fnstsw /* &&  op != op_fldsw */ && ap1
            ->preg != 0)
            return (OCODE*) - 1;
    if (ap1->length != 2)
        return (OCODE*) - 2;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_cmps(void)
{
    AMODE *ap1,  *ap2;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    needpunc(comma, 0);
    ap2 = asm_amode(TRUE);
    if (!ap2)
        return 0;
    if (ap1->mode != am_indisp || ap2->mode != am_indisp)
        return (OCODE*) - 1;
    if (ap1->preg != 6 || ap2->preg != 7)
        return (OCODE*) - 1;
    if (ap1->offset || ap2->offset)
        return (OCODE*) - 1;
    if (!ap1->seg || ap2->seg != 3)
        return (OCODE*) - 1;
    if (!ap1->length && !ap2->length)
        return (OCODE*) - 2;
    return make_ocode(ap1, ap2, 0);
}

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

static OCODE *ope_ins(void)
{
    AMODE *ap1,  *ap2;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    needpunc(comma, 0);
    ap2 = asm_amode(TRUE);
    if (!ap2)
        return 0;
    if (ap1->mode != am_indisp || ap2->mode != am_dreg)
        return (OCODE*) - 1;
    if (ap1->offset)
        return (OCODE*) - 1;
    if (ap1->preg != 7 || ap2->preg != 2)
        return (OCODE*) - 1;
    if (ap2->seg || ap1->seg != 3)
        return (OCODE*) - 1;
    if (ap2->length != 2 || !ap1->length)
        return (OCODE*) - 2;
    return make_ocode(ap1, ap2, 0);
}

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

static OCODE *ope_lods(void)
{
    AMODE *ap1,  *ap2;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_indisp || ap1->offset)
        return (OCODE*) - 1;
    if (ap1->preg != 6)
        return (OCODE*) - 1;
    if (!ap1->length)
        return (OCODE*) - 2;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_movs(void)
{
    AMODE *ap1,  *ap2;
    ap2 = asm_amode(TRUE);
    if (!ap2)
        return 0;
    needpunc(comma, 0);
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_indisp || ap2->mode != am_indisp)
        return (OCODE*) - 1;
    if (ap1->preg != 6 || ap2->preg != 7)
        return (OCODE*) - 1;
    if (ap1->offset || ap2->offset)
        return (OCODE*) - 1;
    if (!ap1->seg || ap2->seg != 3)
        return (OCODE*) - 1;
    if (!ap1->length && !ap2->length)
        return (OCODE*) - 2;
    return make_ocode(ap2, ap1, 0);
}

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

static OCODE *ope_outs(void)
{
    AMODE *ap1,  *ap2;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    needpunc(comma, 0);
    ap2 = asm_amode(TRUE);
    if (!ap2)
        return 0;
    if (ap2->mode != am_indisp || ap1->mode != am_dreg || ap2->offset)
        return (OCODE*) - 1;
    if (ap2->preg != 6 || ap1->preg != 2)
        return (OCODE*) - 1;
    if (ap1->seg || ap2->seg != 2)
        return (OCODE*) - 1;
    if (ap1->length != 2 || !ap2->length)
        return (OCODE*) - 2;
    return make_ocode(ap1, ap2, 0);

}

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

static OCODE *ope_scas(void)
{
    AMODE *ap1,  *ap2;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_indisp || ap1->offset)
        return (OCODE*) - 1;
    if (ap1->preg != 7)
        return (OCODE*) - 1;
    if (ap1->seg != 3)
        return (OCODE*) - 1;
    if (!ap1->length)
        return (OCODE*) - 2;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_xlat(void)
{
    AMODE *ap1,  *ap2;
    ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_indisp || ap1->offset)
        return (OCODE*) - 1;
    if (ap1->preg != 3)
        return (OCODE*) - 1;
    if (ap1->length && ap1->length != 1)
        return (OCODE*) - 2;
    ap1->length = 1;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_reg32(void)
{
    AMODE *ap1 = asm_amode(TRUE);
    if (!ap1)
        return 0;
    if (ap1->mode != am_dreg)
        return (OCODE*) - 1;
    if (ap1->length != 4)
        return (OCODE*) - 2;
    return make_ocode(ap1, 0, 0);
}

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

static OCODE *ope_stos(void)
{
    return ope_scas();
}

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

OCODE *(*funcs[])(void) = 
{
    0, ope_math, ope_arpl, ope_bound, ope_bitscan, ope_bit, ope_call,
        ope_incdec, ope_rm, ope_enter, ope_imul, ope_in, ope_imm8, ope_relbra,
        ope_relbr8, ope_jmp, ope_regrm, ope_loadseg, ope_lgdt, ope_lidt,
        ope_rm16, ope_mov, ope_movsx, ope_out, ope_pushpop, ope_shift, ope_ret,
        ope_set, ope_shld, ope_test, ope_xchg, ope_fmath, ope_fmathp,
        ope_fmathi, ope_fcom, ope_freg, ope_ficom, ope_fild, ope_fist, ope_fld,
        ope_fst, ope_fstp, ope_fucom, ope_fxch, ope_mn, ope_m16, ope_cmps,
        ope_ins, ope_lods, ope_movs, ope_outs, ope_scas, ope_stos, ope_xlat,
        ope_reg32
};
SNODE *asm_statement(int shortfin)
{
    SNODE *snp = 0,  **snpp = &snp;
    OCODE *rv;
    ENODE *node;
    ASMNAME *ki;
    int iserr = 0;
    lastsym = 0;
    do
    {
        (*snpp) = xalloc(sizeof(SNODE));
        (*snpp)->stype = st_asm;
        (*snpp)->label = 0;
        (*snpp)->exp = 0;
        (*snpp)->next = 0;
        if (lastst != kw_asminst)
        {
            if (lastst == kw_int)
            {
                getsym();
                op = op_int;
                rv = ope_imm8();
                goto join;
            }
            node = asm_label();
            if (!node)
                return (*snpp);
            asmline = shortfin;
            if (lastst == semicolon)
                getsym();
            (*snpp)->stype = st_label;
            (*snpp)->label = (SNODE*)node->v.i;
            return (*snpp);
        }
        ki = keyimage;
        op = asm_op();
        if (op ==  - 1)
            return (*snpp);
        if (ki->amode == 0)
        {
            rv = xalloc(sizeof(OCODE));
            rv->oper1 = rv->oper2 = rv->oper3 = 0;
        }
        else
        {
            rv = (*funcs[ki->amode])();
            join: if (!rv || rv == (OCODE*) - 1 || rv == (OCODE*) - 2)
            {
                if (rv == (OCODE*) - 1)
                    asm_err(ERR_AILLADDRESS);
                if (rv == (OCODE*) - 2)
                    asm_err(ERR_AINVSIZE);
                iserr = 1;
                return (snp);
            }
        }
        if (rv->oper1 && rv->oper2)
        {
            if (!rv->oper1->length)
            if (!rv->oper2->length)
            {
                asm_err(ERR_AINVSIZE);
                iserr = 1;
            }
            else
                rv->oper1->length = rv->oper2->length;
            else
                if (!rv->oper2->length && ki->amode != OPE_BOUND && ki->amode 
                    != OPE_LOADSEG)
                    rv->oper2->length = rv->oper1->length;
        }
        rv->noopt = !prm_asmopt;
        rv->opcode = op;
        rv->fwd = rv->back = 0;
        (*snpp)->exp = rv;
        snpp = &(*snpp)->next;
    }
    while (op == op_rep || op == op_repnz || op == op_repz || op == op_repe ||
        op == op_repne || op == op_lock);
    asmline = shortfin;
    if (lastst == semicolon)
        getsym();
    return (snp);
}

⌨️ 快捷键说明

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