📄 inasm386.c
字号:
sz = regimage->size;
getsym();
}
break;
case openbr:
rv = asm_mem();
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 iconst:
case iuconst:
case lconst:
case luconst:
case cconst:
rv = make_immed(ival);
getsym();
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 = lastsym->tp->size;
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;
switch(ap1->length) {
case 1:
return (OCODE *)-1;
case 2:
if (ap2->length != 4) {
return (OCODE *) -2;
}
break;
case 4:
if (ap2->length != 8) {
return (OCODE *) -2;
}
break;
}
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_bitscan (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,TRUE))
return (OCODE *)-1;
if (ap1->length == 1 || ap2->length != ap1->length)
return (OCODE *) -2;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_bit (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_immed && ap2->mode != am_dreg)
return (OCODE *)-1;
if (ap1->length == 1 || ap2->mode == am_dreg && ap2->length == 1)
return (OCODE *) -2;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_call (void)
{
AMODE *ap1=asm_amode(TRUE);
if (!ap1)
return 0;
if (ap1->mode == am_immed) {
if (ap1->offset->nodetype != en_nalabcon && ap1->offset->nodetype != en_labcon
&& ap1->offset->nodetype != en_napccon || ap1->seg)
return (OCODE *)-1;
}
else {
if (!isrm(ap1,TRUE))
return (OCODE *)-1;
if ((ap1->length != 4) && (ap1->length != 6))
return (OCODE *) -2;
}
return make_ocode(ap1,0,0);
}
static OCODE *ope_incdec (void)
{
AMODE *ap1=asm_amode(TRUE);
if (!ap1)
return 0;
if (!isrm(ap1,TRUE))
return (OCODE *)-1;
if (ap1->length >4) {
return (OCODE *) -2;
}
return make_ocode(ap1,0,0);
}
static OCODE *ope_rm (void)
{
return(ope_incdec());
}
static OCODE *ope_enter (void)
{
AMODE *ap1, *ap2;
ap1 = asm_immed();
if (!ap1)
return 0;
needpunc(comma,0);
ap2 = asm_immed();
if (!ap2)
return 0;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_imul (void)
{
AMODE *ap1 = asm_amode(TRUE),*ap2=0,*ap3=0;
if (!ap1)
return 0;
if (!isrm(ap1,TRUE))
return (OCODE *)-1;
if (lastst == comma) {
getsym();
ap2 = asm_amode(TRUE);
if (lastst == comma) {
getsym();
ap3 = asm_amode(TRUE);
}
}
if (ap2) {
if (ap1->mode != am_dreg || ap1->length == 1)
return (OCODE *)-1;
if (!isrm(ap2,TRUE) && ap2->mode != am_immed)
return (OCODE *)-1;
if (ap3)
if (ap2->mode == am_immed || ap3->mode != am_immed)
return (OCODE *)-1;
}
return make_ocode(ap1,ap2,ap3);
}
static OCODE *ope_in (void)
{
AMODE *ap1 = asm_amode(TRUE),*ap2;
if (!ap1)
return 0;
if (ap1-> mode != am_dreg || ap1->preg != 0)
return (OCODE *)-1;
needpunc(comma,0);
ap2 = asm_amode(TRUE);
if (!ap2)
return 0;
if (ap2->mode != am_immed &&( ap2->mode != am_dreg || ap2->preg != 2 || ap2->length !=2))
return (OCODE *)-1;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_imm8 (void)
{
AMODE *ap1 = asm_immed();
if (!ap1)
return 0;
return make_ocode(ap1,0,0);
}
static OCODE *ope_relbra (void)
{
AMODE *ap1=asm_amode(TRUE);
if (!ap1)
return 0;
if (ap1->mode != am_immed)
return (OCODE *)-1;
if (ap1->offset->nodetype != en_nalabcon && ap1->offset->nodetype != en_labcon)
return (OCODE *)-1;
return make_ocode(ap1,0,0);
}
static OCODE *ope_relbr8 (void)
{
return ope_relbra();
}
static OCODE *ope_jmp (void)
{
return ope_call();
}
static OCODE *ope_regrm (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,TRUE))
return (OCODE *)-1;
if (op == op_lea && ap2->mode == am_dreg)
return (OCODE *)-1;
if (ap2->length && ap1->length != ap2->length || ap1->length == 1)
return (OCODE *)-2;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_loadseg (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,TRUE))
return (OCODE *)-1;
if (ap1->length != 4 || ap2->length != 6)
return (OCODE *)-1;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_lgdt (void)
{
AMODE *ap1,*ap2;
ap1 = asm_amode(TRUE);
if (!ap1)
return 0;
if (!isrm(ap1,FALSE) || ap1->length != 6)
return (OCODE *)-1;
return make_ocode(ap1,0,0);
}
static OCODE *ope_lidt (void)
{
return ope_lgdt();
}
static OCODE *ope_rm16 (void)
{
AMODE *ap1,*ap2;
ap1 = asm_amode(TRUE);
if (!ap1)
return 0;
if (!isrm(ap1,TRUE) || ap1->length != 2)
return (OCODE *)-1;
return make_ocode(ap1,0,0);
}
static OCODE *ope_mov (void)
{
AMODE *ap1 = asm_amode(TRUE),*ap2;
if (!ap1)
return 0;
if (!isrm(ap1,TRUE) && ap1->mode != am_seg && ap1->mode != am_screg && ap1->mode != am_sdreg && ap1->mode != am_streg)
return (OCODE *)-1;
needpunc(comma,0);
ap2 = asm_amode(TRUE);
if (!ap2)
return 0;
if (ap1->mode == am_dreg) {
if (!isrm(ap2,TRUE) && ap2->mode != am_immed && (ap2->length != 4 || (ap2->mode != am_screg && ap2->mode != am_sdreg && ap2->mode != am_streg)))
return (OCODE *)-1;
}
else if (isrm(ap1,TRUE)) {
if (ap2->mode != am_dreg && ap2->mode != am_immed && ap2->mode != am_seg)
return (OCODE *)-1;
}
else if (ap1->mode == am_seg) {
if (!isrm(ap2,TRUE))
return (OCODE *)-1;
}
else if (ap2->length != 4 || ap2->mode != am_dreg)
return (OCODE *)-1;
if (ap1->length && ap2->length && ap1->length != ap2->length)
return (OCODE *) -2;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_movsx (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,TRUE))
return (OCODE *)-1;
if (!ap2->length || ap1->length <= ap2->length) {
asm_err(ERR_AINVSIZE);
}
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_out (void)
{
AMODE *ap1 = asm_amode(TRUE),*ap2;
if (!ap1)
return 0;
if (ap1->mode != am_immed &&( ap1->mode != am_dreg || ap1->preg != 2 || ap1->length !=2))
return (OCODE *)-1;
needpunc(comma,0);
ap2 = asm_amode(TRUE);
if (!ap2)
return 0;
if (ap2-> mode != am_dreg || ap2->preg != 0)
return (OCODE *)-1;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_pushpop (void)
{
AMODE *ap1;
ap1 = asm_amode(TRUE);
if (!ap1)
return 0;
if (!isrm(ap1,TRUE) && ap1->mode != am_seg && ap1->mode != am_immed || (ap1->mode == am_immed && op == op_pop))
return (OCODE *)-1;
if (ap1->mode != am_immed && ap1->length !=2 && ap1->length != 4 ) {
return (OCODE *) -2;
}
if (op == op_pop && ap1->mode == am_seg && ap1->seg == 1)
return (OCODE *) -1;
return make_ocode (ap1,0,0);
}
static OCODE *ope_shift (void)
{
AMODE *ap1,*ap2;
ap1 = asm_amode(2);
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_immed && ap2->mode != am_dreg)
return (OCODE *)-1;
if (ap2->mode == am_dreg)
if (ap2->preg != 1 || ap2->length != 1)
return (OCODE *)-1;
return make_ocode(ap1,ap2,0);
}
static OCODE *ope_ret (void)
{
AMODE *ap1 ;
if (lastst != iconst)
return make_ocode(0,0,0);
ap1 = asm_amode(TRUE);
return make_ocode(ap1,0,0);
}
static OCODE *ope_set (void)
{
AMODE *ap1;
ap1 = asm_amode(TRUE);
if (!ap1)
return 0;
if (!isrm(ap1,TRUE) || ap1 ->length != 1)
return (OCODE *)-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -