📄 inasm386.c
字号:
asm_err(ERR_AMODEEXPECT);
return 0;
}
regimage = keyimage;
return sz;
}
//-------------------------------------------------------------------------
static int getscale(int *scale)
{
if (lastst == star)
{
getsym();
if (lastst == iconst && ! *scale)
if (ival == 1 || ival == 2 || ival == 4 || ival == 8)
{
if (ival < 3)
ival--;
else
ival = ival / 4+1;
*scale = ival;
getsym();
return 1;
}
asm_err(ERR_ASCALE);
*scale = - 1;
return 1;
}
return 0;
}
//-------------------------------------------------------------------------
int asm_enterauto(ENODE *node, int *reg1, int *reg2)
{
if (node && (node->nodetype == en_autocon || node->nodetype == en_autoreg))
{
int *vreg;
if (*reg1 >= 0 && *reg2 >= 0)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
if (*reg1 < 0)
vreg = reg1;
else
vreg = reg2;
*vreg = EBP;
return 1;
}
return 2;
}
//-------------------------------------------------------------------------
static int asm_structsize(void)
{
if (lastsym->tp->type == bt_struct)
{
if (lastsym->tp->size == 6)
return 7;
if (lastsym->tp->size == 4)
return 4;
if (lastsym->tp->size == 1)
return 1;
if (lastsym->tp->size == 2)
return 2;
return 1000;
}
else
return lastsym->tp->size;
}
//-------------------------------------------------------------------------
static AMODE *asm_mem(void)
{
int reg1 = - 1, reg2 = - 1, scale = 0, temp, sz = 0, seg = 0;
ENODE *node = 0;
AMODE *rv;
int first = TRUE;
int gotident = FALSE, autonode = FALSE;
while (TRUE)
{
int rg;
cont: getsym();
regimage = keyimage;
if (regimage)
rg = regimage->regnum;
switch (lastst)
{
case kw_asmreg:
regimage = keyimage;
if (regimage->regtype == am_seg)
{
if (seg)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
seg = rg;
getsym();
if (lastst != colon)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
goto cont;
}
if (regimage->regtype != am_dreg || regimage->size != 4)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
if (reg1 >= 0)
{
if (reg2 >= 0)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
reg2 = rg;
getsym();
getscale(&scale);
if (scale == - 1)
return 0;
}
else
{
getsym();
if (getscale(&scale))
{
if (scale == - 1)
return 0;
if (reg2 >= 0)
{
reg1 = reg2;
}
reg2 = rg;
}
else
{
reg1 = rg;
}
}
break;
case minus:
case plus:
case iuconst:
case lconst:
case luconst:
case cconst:
case iconst:
if (node)
node = makenode(en_add, node, makeintnode(en_icon, intexpr
(0)));
else
node = makeintnode(en_icon, intexpr(0));
break;
case id:
if (gotident)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
node = asm_ident();
gotident = TRUE;
sz = asm_structsize();
switch (asm_enterauto(node, ®1, ®2))
{
case 0:
return 0;
case 1:
autonode = TRUE;
break;
case 2:
autonode = FALSE;
break;
}
break;
default:
asm_err(ERR_AILLADDRESS);
return 0;
}
if (lastst == closebr)
{
getsym();
break;
}
first = FALSE;
if (lastst != plus && lastst != minus)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
backup(lastst);
}
if ((reg2 == 4 || reg2 == 5) && scale > 1)
{
asm_err(ERR_AINVINDXMODE);
return 0;
}
rv = xalloc(sizeof(AMODE));
if (node)
{
rv->offset = node;
}
if (reg1 >= 0)
{
rv->preg = reg1;
if (reg2 >= 0)
{
rv->sreg = reg2;
rv->scale = scale;
rv->mode = am_indispscale;
}
else
{
rv->mode = am_indisp;
}
}
else
if (reg2 >= 0)
{
rv->preg = - 1;
rv->sreg = reg2;
rv->scale = scale;
rv->mode = am_indispscale;
}
else
rv->mode = am_direct;
rv->seg = seg;
return rv;
}
//-------------------------------------------------------------------------
static AMODE *asm_amode(int nosegreg)
{
AMODE *rv = xalloc(sizeof(AMODE));
int sz = 0, seg = 0;
lastsym = 0;
switch (lastst)
{
case iconst:
case iuconst:
case lconst:
case luconst:
case cconst:
case minus:
case plus:
case kw_asmreg:
case openbr:
case id:
break;
default:
asm_err(ERR_AMODEEXPECT);
return 0;
}
if (lastst == kw_asmreg)
{
regimage = keyimage;
if (regimage->regtype == am_ext)
{
sz = asm_getsize();
regimage = keyimage;
}
}
loop: switch (lastst)
{
case kw_asmreg:
if (regimage->regtype == am_ext)
{
asm_err(ERR_ATOOMANYSPECS);
return 0;
}
if (regimage->regtype == am_freg)
{
getsym();
if (lastst == openpa)
{
getsym();
if (lastst != iconst || ival < 0 || ival > 7)
{
asm_err(ERR_ANEEDFP);
return 0;
}
getsym();
needpunc(closepa, 0);
}
else
ival = 0;
rv->preg = ival;
rv->mode = am_freg;
sz = 10;
}
else if (regimage->regtype == am_seg)
{
if (rv->seg)
{
asm_err(ERR_ATOOMANYSEGS);
return 0;
}
rv->seg = seg = regimage->regnum;
getsym();
if (lastst == colon)
{
getsym();
goto loop;
}
rv->mode = am_seg;
sz = regimage->size;
}
else
{
rv->preg = regimage->regnum;
rv->mode = regimage->regtype;
sz = rv->length = regimage->size;
getsym();
}
break;
case openbr:
rv = asm_mem();
if (rv && rv->seg)
seg = rv->seg;
break;
case id:
rv->mode = am_immed;
rv->offset = asm_ident();
rv->length = 4;
if (rv->offset->nodetype == en_autocon || rv->offset->nodetype ==
en_autoreg)
{
asm_err(ERR_AUSELEA);
return 0;
}
break;
case minus:
case plus:
case iconst:
case iuconst:
case lconst:
case luconst:
case cconst:
rv = make_immed(intexpr(0));
break;
default:
asm_err(ERR_AILLADDRESS);
return 0;
}
if (rv)
{
if (rv->seg)
if (nosegreg || rv->mode != am_dreg)
if (rv->mode != am_direct && rv->mode != am_indisp && rv->mode !=
am_indispscale && rv->mode != am_seg)
{
asm_err(ERR_ATOOMANYSEGS);
return 0;
}
if (!rv->length)
if (sz)
rv->length = sz;
else if (lastsym)
rv->length = asm_structsize();
if (rv->length < 0)
rv->length = - rv->length;
rv->seg = seg;
}
return rv;
}
//-------------------------------------------------------------------------
static AMODE *asm_immed(void)
{
AMODE *rv;
switch (lastst)
{
case iconst:
case iuconst:
case lconst:
case luconst:
case cconst:
rv = make_immed(ival);
rv->length = 4;
getsym();
return rv;
}
return 0;
}
//-------------------------------------------------------------------------
int isrm(AMODE *ap, int dreg_allowed)
{
switch (ap->mode)
{
case am_dreg:
return dreg_allowed;
case am_indisp:
case am_direct:
case am_indispscale:
return 1;
default:
return 0;
}
}
//-------------------------------------------------------------------------
AMODE *getimmed(void)
{
AMODE *rv;
switch (lastst)
{
case iconst:
case iuconst:
case lconst:
case luconst:
case cconst:
rv = make_immed(ival);
getsym();
return rv;
default:
return 0;
}
}
//-------------------------------------------------------------------------
enum e_op asm_op(void)
{
int op;
if (lastst != kw_asminst)
{
asm_err(ERR_AINVOP);
return - 1;
} op = keyimage->atype;
getsym();
floating = op >= op_f2xm1;
return op;
}
//-------------------------------------------------------------------------
static OCODE *make_ocode(AMODE *ap1, AMODE *ap2, AMODE *ap3)
{
OCODE *o = xalloc(sizeof(OCODE));
o->oper1 = ap1;
o->oper2 = ap2;
o->oper3 = ap3;
return o;
}
//-------------------------------------------------------------------------
static OCODE *ope_math(void)
{
AMODE *ap1, *ap2;
ap1 = asm_amode(TRUE);
if (!ap1)
return 0;
if (!isrm(ap1, TRUE))
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode(TRUE);
if (!ap2)
return 0;
if (ap1->mode != am_dreg)
{
if (ap2->mode != am_immed && ap2->mode != am_dreg)
return (OCODE*) - 1;
}
else
if (!isrm(ap2, TRUE) && ap2->mode != am_immed)
return (OCODE*) - 1;
if (ap2->mode != am_immed)
if (ap1->length && ap2->length && ap1->length != ap2->length)
return (OCODE*) - 2;
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_arpl(void)
{
AMODE *ap1, *ap2;
ap1 = asm_amode(TRUE);
if (!ap1)
return 0;
if (!isrm(ap1, TRUE))
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode(TRUE);
if (!ap2)
return 0;
if (ap2->mode != am_dreg)
return (OCODE*) - 1;
if (!ap1->length || !ap2->length || ap1->length != ap2->length || ap1
->length != 2)
return (OCODE*) - 2;
return make_ocode(ap1, ap2, 0);
}
//-------------------------------------------------------------------------
static OCODE *ope_bound(void)
{
AMODE *ap1, *ap2;
ap1 = asm_amode(TRUE);
if (!ap1)
return 0;
if (ap1->mode != am_dreg)
return (OCODE*) - 1;
needpunc(comma, 0);
ap2 = asm_amode(TRUE);
if (!ap2)
return 0;
if (!isrm(ap2, FALSE))
return (OCODE*) - 1;
if (ap2->length)
return (OCODE*) - 2;
#ifdef XXXXX
switch (ap1->length)
{
case 1:
return (OCODE*) - 1;
case 2:
if (ap2->length != 4)
{
return (OCODE*) - 2;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -