📄 inasm386.c
字号:
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 + -