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

📄 parser.c

📁 一个免费的汇编语言编译器的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	      case S_TWORD:
		if (!setsize)
		    result->oprs[operand].type |= BITS80;
		setsize = 1;
		break;
	      case S_TO:
		result->oprs[operand].type |= TO;
		break;
	      case S_STRICT:
		result->oprs[operand].type |= STRICT;
		break;
	      case S_FAR:
		result->oprs[operand].type |= FAR;
		break;
	      case S_NEAR:
		result->oprs[operand].type |= NEAR;
		break;
	      case S_SHORT:
		result->oprs[operand].type |= SHORT;
		break;
	      default:
		error (ERR_NONFATAL, "invalid operand size specification");
	    }
	    i = stdscan(NULL, &tokval);
	}

	if (i == '[' || i == '&') {    /* memory reference */
	    mref = TRUE;
	    bracket = (i == '[');
	    i = stdscan(NULL, &tokval);
	    if (i == TOKEN_SPECIAL) {  /* check for address size override */
		if (tasm_compatible_mode) {
		  switch ((int)tokval.t_integer) {
		    /* For TASM compatibility a size override inside the
		     * brackets changes the size of the operand, not the
		     * address type of the operand as it does in standard
		     * NASM syntax. Hence:
		     *
		     *	mov	eax,[DWORD val]
		     *
		     * is valid syntax in TASM compatibility mode. Note that
		     * you lose the ability to override the default address
		     * type for the instruction, but we never use anything
		     * but 32-bit flat model addressing in our code.
		     */
		    case S_BYTE:
		      result->oprs[operand].type |= BITS8;
		      break;
		    case S_WORD:
		      result->oprs[operand].type |= BITS16;
		      break;
		    case S_DWORD:
		    case S_LONG:
		      result->oprs[operand].type |= BITS32;
		      break;
		    case S_QWORD:
		      result->oprs[operand].type |= BITS64;
		      break;
		    case S_TWORD:
		      result->oprs[operand].type |= BITS80;
		      break;
		    default:
		      error (ERR_NONFATAL, "invalid operand size specification");
		  }
		} else {
		  /* Standard NASM compatible syntax */
		  switch ((int)tokval.t_integer) {
		    case S_NOSPLIT:
		      result->oprs[operand].eaflags |= EAF_TIMESTWO;
		      break;
		    case S_BYTE:
		      result->oprs[operand].eaflags |= EAF_BYTEOFFS;
		      break;
		    case S_WORD:
		      result->oprs[operand].addr_size = 16;
		      result->oprs[operand].eaflags |= EAF_WORDOFFS;
		      break;
		    case S_DWORD:
		    case S_LONG:
		      result->oprs[operand].addr_size = 32;
		      result->oprs[operand].eaflags |= EAF_WORDOFFS;
		      break;
		    default:
		      error (ERR_NONFATAL, "invalid size specification in"
			     " effective address");
		  }
		}
		i = stdscan(NULL, &tokval);
	    }
	} else {		       /* immediate operand, or register */
	    mref = FALSE;
	    bracket = FALSE;	       /* placate optimisers */
	}

	if((result->oprs[operand].type & FAR) && !mref &&
	     result->opcode != I_JMP && result->opcode != I_CALL)
	{
	    error (ERR_NONFATAL, "invalid use of FAR operand specifier");
	}

	value = evaluate (stdscan, NULL, &tokval,
			  &result->oprs[operand].opflags,
			  critical, error, &hints);
	i = tokval.t_type;
	if (result->oprs[operand].opflags & OPFLAG_FORWARD) {
	    result->forw_ref = TRUE;
	}
	if (!value) {		       /* error in evaluator */
	    result->opcode = -1;       /* unrecoverable parse error: */
	    return result;	       /* ignore this instruction */
	}
	if (i == ':' && mref) {	       /* it was seg:offset */
	    /*
	     * Process the segment override.
	     */
	    if (value[1].type!=0 || value->value!=1 ||
		REG_SREG & ~reg_flags[value->type])
		error (ERR_NONFATAL, "invalid segment override");
	    else if (result->nprefix == MAXPREFIX)
		error (ERR_NONFATAL,
		       "instruction has more than %d prefixes",
		       MAXPREFIX);
	    else
		result->prefixes[result->nprefix++] = value->type;

	    i = stdscan(NULL, &tokval);	       /* then skip the colon */
	    if (i == TOKEN_SPECIAL) {  /* another check for size override */
		switch ((int)tokval.t_integer) {
		  case S_WORD:
		    result->oprs[operand].addr_size = 16;
		    break;
		  case S_DWORD:
		  case S_LONG:
		    result->oprs[operand].addr_size = 32;
		    break;
		  default:
		    error (ERR_NONFATAL, "invalid size specification in"
			   " effective address");
		}
		i = stdscan(NULL, &tokval);
	    }
	    value = evaluate (stdscan, NULL, &tokval,
			      &result->oprs[operand].opflags,
			      critical, error, &hints);
	    i = tokval.t_type;
	    if (result->oprs[operand].opflags & OPFLAG_FORWARD) {
		result->forw_ref = TRUE;
	    }
	    /* and get the offset */
	    if (!value) {	       /* but, error in evaluator */
		result->opcode = -1;   /* unrecoverable parse error: */
		return result;	       /* ignore this instruction */
	    }
	}
	if (mref && bracket) {	       /* find ] at the end */
	    if (i != ']') {
		error (ERR_NONFATAL, "parser: expecting ]");
		do {		       /* error recovery again */
		    i = stdscan(NULL, &tokval);
		} while (i != 0 && i != ',');
	    } else		       /* we got the required ] */
		i = stdscan(NULL, &tokval);
	} else {		       /* immediate operand */
	    if (i != 0 && i != ',' && i != ':') {
		error (ERR_NONFATAL, "comma or end of line expected");
		do {		       /* error recovery */
		    i = stdscan(NULL, &tokval);
		} while (i != 0 && i != ',');
	    } else if (i == ':') {
		result->oprs[operand].type |= COLON;
	    }
	}

	/* now convert the exprs returned from evaluate() into operand
	 * descriptions... */

	if (mref) {		       /* it's a memory reference */
	    expr *e = value;
	    int b, i, s;	       /* basereg, indexreg, scale */
	    long o;		       /* offset */

	    b = i = -1, o = s = 0;
	    result->oprs[operand].hintbase = hints.base;
	    result->oprs[operand].hinttype = hints.type;

	    if (e->type && e->type <= EXPR_REG_END)   /* this bit's a register */
	    {
		if (e->value == 1) /* in fact it can be basereg */
		    b = e->type;
		else	       /* no, it has to be indexreg */
		    i = e->type, s = e->value;
		e++;
	    }
	    if (e->type && e->type <= EXPR_REG_END)   /* it's a 2nd register */
	    {
		if (b != -1)               /* If the first was the base, ... */
		    i = e->type, s = e->value;  /* second has to be indexreg */

		else if (e->value != 1)          /* If both want to be index */
		{
		    error(ERR_NONFATAL, "beroset-p-592-invalid effective address");
		    result->opcode = -1;
		    return result;
		} 
		else
		    b = e->type;
		e++;
	    }
	    if (e->type != 0) {	       /* is there an offset? */
		if (e->type <= EXPR_REG_END)  /* in fact, is there an error? */
		{
		    error (ERR_NONFATAL, "beroset-p-603-invalid effective address");
		    result->opcode = -1;
		    return result;
		} 
		else 
		{
		    if (e->type == EXPR_UNKNOWN) {
			o = 0;	                     /* doesn't matter what */
			result->oprs[operand].wrt = NO_SEG;     /* nor this */
			result->oprs[operand].segment = NO_SEG;  /* or this */
			while (e->type) e++;   /* go to the end of the line */
		    } 
		    else 
		    {
			if (e->type == EXPR_SIMPLE) {
			    o = e->value;
			    e++;
			}
			if (e->type == EXPR_WRT) {
			    result->oprs[operand].wrt = e->value;
			    e++;
			} else
			    result->oprs[operand].wrt = NO_SEG;
			/*
			 * Look for a segment base type.
			 */
			if (e->type && e->type < EXPR_SEGBASE) {
			    error (ERR_NONFATAL, "beroset-p-630-invalid effective address");
			    result->opcode = -1;
			    return result;
			}
			while (e->type && e->value == 0)
			    e++;
			if (e->type && e->value != 1) {
			    error (ERR_NONFATAL, "beroset-p-637-invalid effective address");
			    result->opcode = -1;
			    return result;
			}
			if (e->type) {
			    result->oprs[operand].segment =
				e->type - EXPR_SEGBASE;
			    e++;
			} else
			    result->oprs[operand].segment = NO_SEG;
			while (e->type && e->value == 0)
			    e++;
			if (e->type) {
			    error (ERR_NONFATAL, "beroset-p-650-invalid effective address");
			    result->opcode = -1;
			    return result;
			}
		    }
		}
	    } else {
		o = 0;
		result->oprs[operand].wrt = NO_SEG;
		result->oprs[operand].segment = NO_SEG;
	    }

	    if (e->type != 0) {    /* there'd better be nothing left! */
		error (ERR_NONFATAL, "beroset-p-663-invalid effective address");
		result->opcode = -1;
		return result;
	    }

	    result->oprs[operand].type |= MEMORY;
	    if (b==-1 && (i==-1 || s==0))
		result->oprs[operand].type |= MEM_OFFS;
	    result->oprs[operand].basereg = b;
	    result->oprs[operand].indexreg = i;
	    result->oprs[operand].scale = s;
	    result->oprs[operand].offset = o;
	} 
	else		                      /* it's not a memory reference */
	{
	    if (is_just_unknown(value)) {     /* it's immediate but unknown */
		result->oprs[operand].type |= IMMEDIATE;
		result->oprs[operand].offset = 0;   /* don't care */
		result->oprs[operand].segment = NO_SEG; /* don't care again */
		result->oprs[operand].wrt = NO_SEG;/* still don't care */
	    } 
	    else if (is_reloc(value))         /* it's immediate */
	    {
		result->oprs[operand].type |= IMMEDIATE;
		result->oprs[operand].offset = reloc_value(value);
		result->oprs[operand].segment = reloc_seg(value);
		result->oprs[operand].wrt = reloc_wrt(value);
		if (is_simple(value)) {
		    if (reloc_value(value)==1)
			result->oprs[operand].type |= UNITY;
		    if (optimizing>=0 &&
			!(result->oprs[operand].type & STRICT)) {
  		        if (reloc_value(value) >= -128 &&
		                 reloc_value(value) <= 127)
		            result->oprs[operand].type |= SBYTE;
		    }
		}
	    } 
	    else	       /* it's a register */
	    {
		if (value->type>=EXPR_SIMPLE || value->value!=1) {
		    error (ERR_NONFATAL, "invalid operand type");
		    result->opcode = -1;
		    return result;
		}

		/*
		 * check that its only 1 register, not an expression...
		 */
		for (i = 1; value[i].type; i++)
		    if (value[i].value) {
			error (ERR_NONFATAL, "invalid operand type");
			result->opcode = -1;
			return result;
		    }

		/* clear overrides, except TO which applies to FPU regs */
		if (result->oprs[operand].type & ~TO) {
		    /*
		     * we want to produce a warning iff the specified size
		     * is different from the register size
		     */
		    i = result->oprs[operand].type & SIZE_MASK;
		}
		else
		    i = 0;

		result->oprs[operand].type &= TO;
		result->oprs[operand].type |= REGISTER;
		result->oprs[operand].type |= reg_flags[value->type];
		result->oprs[operand].basereg = value->type;

		if (i && (result->oprs[operand].type & SIZE_MASK) != i)
		    error (ERR_WARNING|ERR_PASS1,
			   "register size specification ignored");
	    }
	}
    }

    result->operands = operand;       /* set operand count */

    while (operand<3)		       /* clear remaining operands */
	result->oprs[operand++].type = 0;

    /*
     * Transform RESW, RESD, RESQ, REST into RESB.
     */
    switch (result->opcode) {
      case I_RESW: result->opcode=I_RESB; result->oprs[0].offset*=2; break;
      case I_RESD: result->opcode=I_RESB; result->oprs[0].offset*=4; break;
      case I_RESQ: result->opcode=I_RESB; result->oprs[0].offset*=8; break;
      case I_REST: result->opcode=I_RESB; result->oprs[0].offset*=10; break;
    }

    return result;
}

static int is_comma_next (void) 
{
    char *p;
    int i;
    struct tokenval tv;

    p = stdscan_bufptr;
    i = stdscan (NULL, &tv);
    stdscan_bufptr = p;
    return (i == ',' || i == ';' || !i);
}

void cleanup_insn (insn *i) 
{
    extop *e;

    while (i->eops) {
	e = i->eops;
	i->eops = i->eops->next;
	nasm_free (e);
    }
}

⌨️ 快捷键说明

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