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

📄 inasm386.c

📁 一个c compiler的source code
💻 C
📖 第 1 页 / 共 3 页
字号:
						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 + -