Beispiel #1
0
static int test_register(char * n, asm86_t * a)
{
	int r;
	optype_t optype;

	/* PSEUDO or JUMP */
	if (!a || (a->optype != NONE && a->optype < BYTE))
		return isregister(n);

	/* 
	 * as we assume that instructions without specified operand size like
	 * mov use 32bit ones we must make sure that we are not passing
	 * suchinstruction a register of a different size
	 */
	if (r = isregister(n)) {
		if (IS_REG8(r)) {
			optype = BYTE;
		} else if (IS_REG16(r)) {
			optype = WORD;
		} else if (IS_REG32(r)) {
			optype = OWORD;
		}
	}

	a->optype = (a->optype > optype ? optype : a->optype);

	return r;
}
Beispiel #2
0
static expression_t *gnu_get_oplist(asm86_t * a, int *pn, int deref)
/* Get a comma (or colon for jmpf and callf) separated list of instruction
 * operands.
 */
{
	expression_t *e, *o1, *o2;
	token_t *t;
	int sreg;

	if ((e= gnu_get_operand(a, pn, deref)) == nil) return nil;

	t = get_token(*pn);
	
	if (t->symbol == ':' && IS_REGSEG(sreg = isregister(e->name))) {
		a->seg = segreg2seg(sreg);
		del_expr(e);
		(*pn)++;
		e = gnu_get_oplist(a, pn, deref);
	}
	else if (t->symbol == ',' || t->symbol == ':') {
		o1= e;
		(*pn)++;
		if ((o2= gnu_get_oplist(a, pn, deref)) == nil) {
			del_expr(o1);
			return nil;
		}
		e= new_expr();
		e->operator= ',';
		e->left= o2;
		e->right= o1;
	}
	return e;
}
Beispiel #3
0
int syms_is_global(const char * n)
{
	struct sym *s;

	if (!n || is_number(n) || is_local_label_ref(n) || isregister(n))
		return 0;
	
	/* if not found, it must be extern -> global */
	if (!(s = sym_exists(n)))
		return 1;

	return s->gl;
}
static expression_t *ack_get_operand(int *pn, int deref)
/* Get something like: (memory), offset(base)(index*scale), or simpler. */
{
	expression_t *e, *offset, *base, *index;
	token_t *t;
	int c;

	/* Is it (memory)? */
	if (get_token(*pn)->symbol == '('
		&& ((t= get_token(*pn + 1))->type != T_WORD
			|| !isregister(t->name))
	) {
		/* A memory dereference. */
		(*pn)++;
		if ((offset= ack_get_C_expression(pn)) == nil) return nil;
		if (get_token(*pn)->symbol != ')') {
			parse_err(1, t, "operand syntax error\n");
			del_expr(offset);
			return nil;
		}
		(*pn)++;
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
	}

	/* #constant? */
	if (dialect == NCC && deref
			&& ((c= get_token(*pn)->symbol) == '#' || c == '*')) {
		/* NCC: mov ax,#constant  ->  ACK: mov ax,constant */
		(*pn)++;
		return ack_get_C_expression(pn);
	}

	/* @address? */
	if (dialect == NCC && get_token(*pn)->symbol == '@') {
		/* NCC: jmp @address  ->  ACK: jmp (address) */
		(*pn)++;
		if ((offset= ack_get_operand(pn, deref)) == nil) return nil;
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
	}

	/* Offset? */
	if (get_token(*pn)->symbol != '(') {
		/* There is an offset. */
		if ((offset= ack_get_C_expression(pn)) == nil) return nil;
	} else {
		/* No offset. */
		offset= nil;
	}

	/* (base)? */
	if (get_token(*pn)->symbol == '('
		&& (t= get_token(*pn + 1))->type == T_WORD
		&& isregister(t->name)
		&& get_token(*pn + 2)->symbol == ')'
	) {
		/* A base register expression. */
		base= new_expr();
		base->operator= 'B';
		base->name= copystr(t->name);
		(*pn)+= 3;
	} else {
		/* No base register expression. */
		base= nil;
	}

	/* (index*scale)? */
	if (get_token(*pn)->symbol == '(') {
		/* An index most likely. */
		token_t *m= nil;

		if (!(		/* This must be true: */
			(t= get_token(*pn + 1))->type == T_WORD
			&& isregister(t->name)
			&& (get_token(*pn + 2)->symbol == ')' || (
				get_token(*pn + 2)->symbol == '*'
				&& (m= get_token(*pn + 3))->type == T_WORD
				&& strchr("1248", m->name[0]) != nil
				&& m->name[1] == 0
				&& get_token(*pn + 4)->symbol == ')'
			))
		)) {
			/* Alas it isn't */
			parse_err(1, t, "operand syntax error\n");
			del_expr(offset);
			del_expr(base);
			return nil;
		}
		/* Found an index. */
		index= new_expr();
		index->operator= m == nil ? '1' : m->name[0];
		index->name= copystr(t->name);
		(*pn)+= (m == nil ? 3 : 5);
	} else {
		/* No index. */
		index= nil;
	}

	if (dialect == NCC && deref && base == nil && index == nil
		&& !(offset != nil && offset->operator == 'W'
					&& isregister(offset->name))
	) {
		/* NCC: mov ax,thing  ->  ACK mov ax,(thing) */
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
	}

	if (base == nil && index == nil) {
		/* Return a lone offset as is. */
		e= offset;
	} else {
		e= new_expr();
		e->operator= 'O';
		e->left= offset;
		e->middle= base;
		e->right= index;
	}
	return e;
}
Beispiel #5
0
static expression_t *gnu_get_operand(asm86_t * a, int *pn, int deref)
/* Get something like: $immed, memory, offset(%base,%index,scale), or simpler. */
{
	expression_t *e, *offset, *base, *index;
	token_t *t;
	int c;

	if (get_token(*pn)->symbol == '$') {
		/* An immediate value. */
		(*pn)++;
		return gnu_get_C_expression(pn);
	}

	if (get_token(*pn)->symbol == '*') {
		(*pn)++;
		deref = 1;
#if 0
		if ((offset= gnu_get_operand(a, pn, deref)) == nil) return nil;
#if 0
		e= new_expr();
		e->operator= '(';
		e->middle= offset;
		return e;
#endif
		return offset;
#endif
	}

	if ((get_token(*pn)->symbol == '%')
		&& (t= get_token(*pn + 1))->type == T_WORD
		&& isregister(t->name)
	) {
		/* A register operand. */
		(*pn)+= 2;
		e= new_expr();
		e->operator= 'W';
		e->name= copystr(t->name);
		return e;
	}

	/* Offset? */
	if (get_token(*pn)->symbol != '('
				|| get_token(*pn + 1)->symbol != '%') {
		/* There is an offset. */
		if ((offset= gnu_get_C_expression(pn)) == nil) return nil;
	} else {
		/* No offset. */
		offset= nil;
	}

	/* (%base,%index,scale) ? */
	base= index= nil;
	if (get_token(*pn)->symbol == '(') {
		(*pn)++;

		/* %base ? */
		if (get_token(*pn)->symbol == '%'
			&& (t= get_token(*pn + 1))->type == T_WORD
			&& isregister(t->name)
		) {
			/* A base register expression. */
			base= new_expr();
			base->operator= 'B';
			base->name= copystr(t->name);
			(*pn)+= 2;
		}

		if (get_token(*pn)->symbol == ',') (*pn)++;

		/* %index ? */
		if (get_token(*pn)->symbol == '%'
			&& (t= get_token(*pn + 1))->type == T_WORD
			&& isregister(t->name)
		) {
			/* A index register expression. */
			index= new_expr();
			index->operator= '1';		/* for now */
			index->name= copystr(t->name);
			(*pn)+= 2;
		}

		if (get_token(*pn)->symbol == ',') (*pn)++;

		/* scale ? */
		if ((base != nil || index != nil)
			&& (t= get_token(*pn))->type == T_WORD
			&& strchr("1248", t->name[0]) != nil
			&& t->name[1] == 0
		) {		
			if (index == nil) {
				/* Base is really an index register. */
				index= base;
				base= nil;
			}
			index->operator= t->name[0];
			(*pn)++;
		}

		if (get_token(*pn)->symbol == ')') {
			/* Ending paren. */
			(*pn)++;
		} else {
			/* Alas. */
			parse_err(1, t, "operand syntax error\n");
			del_expr(offset);
			del_expr(base);
			del_expr(index);
			return nil;
		}
	}

	if (base == nil && index == nil) {
		if (deref) {
			/* Return a lone offset as (offset). */
			e= new_expr();
			e->operator= '(';
			e->middle= offset;
		} else {
			/* Return a lone offset as is. */
			e= offset;
		}
	} else {
		e= new_expr();
		e->operator= 'O';
		e->left= offset;

		e->middle= base;
		e->right= index;
	}
	return e;
}