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

📄 operand.c

📁 Intel x86处理器的汇编器
💻 C
📖 第 1 页 / 共 2 页
字号:
				str[i] = *(p+i+1);  i++;			}		} else if (p == s) {		/* head */			while (p+i <= q) {				str[i] = *(p+i); i++;			}		}		str[i] = 0;			o_key_t *okey = (o_key_t *)a64_malloc(sizeof(o_key_t));		/* get operands key word */ 		if (!ops_key->so_key) {		/* this is a source operand */			ops_key->so_key = okey;			} else if (!ops_key->do_key) {  /* this is a dest operand */			ops_key->do_key = okey;		} else if (!ops_key->to_key) {	/* this is a three operand */			ops_key->to_key = okey;		} else {			a64_free(okey);			sprintf(tmp_msg, "at %d: %s\n",				line, "operands over three");						if (str_len(msg) + str_len(tmp_msg)					< ERR_MSG_SIZE)			{				str_cat(msg, tmp_msg);					mount_err_link(0, 0, msg);			} else {				errno |= ERR_OPERAND;				mount_err_link(errno, ops_errmsg, 0);				return errno;			}		}				errno |= get_o_key(okey, str);		if (p <= s) break;		p--;			/*  search next operand */	}			return errno;}/*********************************************************************** function: unsigned int get_attr(o_key_t* o_key); parameter: 	   o_key: a operand key word return value: 		unsigned int operand attribute wordlast change: 02-17-2006 21:10 by mik***********************************************************************/unsigned int get_attr(o_key_t *o_key){	if (!o_key) return 0;	unsigned int o_attr = 0;	if (o_key->reg) {		o_attr |= 0x80000000 >> (o_key->reg & 0x07);		switch (o_key->reg & 0xf0) {		case 0x10:		case 0x20:		case 0x40:		case 0x80:			o_attr |= GPR | ((o_key->reg & 0xf0) >> 4);			break;		case 0xa0: o_attr |= SREG | SIZE16; break;		case 0xc0: o_attr |= CREG | SIZE32; break;		case 0xd0: o_attr |= DREG | SIZE32; break;		case 0xe0: o_attr |= MMX | SIZE64; break;		case 0xf0: o_attr |= XMM | SIZE128; break;		}		} else if (o_key->mem) {		if (!o_key->mem->base && !o_key->mem->index) {			if (o_key->mem->disp)				o_attr |= MOFFSET;		} else 			o_attr |= MEM;		/* get memory operand size */		/* example: case is 32 chang to SIZE32 = cast >> 3 */		o_attr |=  o_key->mem->cast >> 3;	} else if (o_key->imme) {		/* immediate operand not size */		if (o_key->imme->imme_value == 1)			o_attr |= IMME_1; 		else			o_attr |= IMME;			unsigned int size = get_sizeof(o_key->imme->imme_value);		/******************************	 	 * TODO: reserved for imme size 		 * example: (dword)0x0c		 ******************************/		if (o_key->imme->cast) {			o_attr |= (o_key->imme->cast >> 3);		} else {			if (size == 1)				o_attr |= 0x01;			else if (size <= current_bits) {				o_attr |= current_bits >> 3;				o_key->imme->cast = current_bits;			}						}	}	return o_attr;}/************************************************************************  function: errno get_ops_attr(ops_attr_t *ops_attr, ops_key_t *ops_key);  parameter:	    ops_key: operands key words  return value: 	        error if errno is set                successed if errno is 0last change: 02-17-2006 21:32 by mik************************************************************************/errno_t get_ops_attr(ops_attr_t *ops_attr, ops_key_t *ops_key){		if (!ops_attr) 		return ERR_OPERAND;	if (!ops_key) {		/* no operands */		ops_attr->so_attr = 0;		ops_attr->do_attr = 0;		ops_attr->to_attr = 0;		return 0;	}		/* 	   source operand is immediate. 	   dest operand is register	*/	if (ops_key->so_key && ops_key->so_key->imme 		&& ops_key->do_key && ops_key->do_key->reg) {		if (get_sizeof(ops_key->so_key->imme->imme_value) > 				((ops_key->do_key->reg & 0xf0) >> 4)) 		{			mount_err_link(ERR_OPERAND, ops_errmsg, 0);			return ERR_OPERAND;		}	}	ops_attr->so_attr = get_attr(ops_key->so_key);	ops_attr->do_attr = get_attr(ops_key->do_key);	ops_attr->to_attr = get_attr(ops_key->to_key);	if (((OPTYPE(ops_attr->so_attr) == MEM) && 		(OPTYPE(ops_attr->do_attr) == MEM)) || 		((OPTYPE(ops_attr->so_attr) == IMME) &&		(OPTYPE(ops_attr->do_attr) == IMME)))	{		mount_err_link(ERR_OPERAND, ops_errmsg, 0);		return ERR_OPERAND;	}	return 0;}/************** the function get operands type ************last change: 02-18-2006 12:11 by mik***********************************************************/ops_type_t get_ops_type(ops_key_t *ops_key){	ops_type_t ops_type = 0;	if (!ops_key) return 0;		o_key_t *so_key = ops_key->so_key;	o_key_t *do_key = ops_key->do_key;	o_key_t *to_key = ops_key->to_key;	/* get source operand type */	if (so_key) 		ops_type |= so_key->reg ? S_R : so_key->mem ? S_M : 			so_key->imme ? S_I : 0;		/* get dest operand type */	if (do_key) 		ops_type |= do_key->reg ? D_R : do_key->mem ? D_M :			do_key->imme ? D_I : 0;		/* get three operand type */	if (to_key) 		ops_type |= to_key->reg ? T_R : to_key->mem ? T_M : 			to_key->imme ? T_I : 0;		return ops_type;}unsigned int get_o_size(o_key_t *o_key){	unsigned int o_size = 0;	if (!o_key)		return 0;	if (o_key->reg)		o_size = get_reg_size(o_key->reg);	else if (o_key->mem) 		o_size = o_key->mem->cast;	else if (o_key->imme) {		if (o_key->imme->cast)			o_size = o_key->imme->cast;		else if (o_key->imme->imme_value == 0)			o_size = current_bits;		else			o_size = get_sizeof(o_key->imme->imme_value) * 8;	}			return o_size;}/*****************************************************************the function get operands sizelast change: 02-17-2006 21:54 by mik******************************************************************/unsigned int get_ops_size(ops_key_t *ops_key){	unsigned int ops_size = 0;	if (!ops_key) return 0;	o_key_t *so_key = ops_key->so_key;	o_key_t *do_key = ops_key->do_key;	o_key_t *to_key = ops_key->to_key;	if (so_key && !do_key && !to_key) { 	/* only one operand */		if (so_key->reg) {			ops_size = get_reg_size(so_key->reg);					} else if (so_key->mem) {					/* only one operand case: 			 * the operand size must be casted */			ops_size = so_key->mem->cast;		} else if (so_key->imme) {			/**************************************			* TODO: reserver for check imme size 			**************************************/			if (so_key->imme->cast) {				ops_size = so_key->imme->cast;			} else if (so_key->imme->imme_value == 0) {				ops_size = current_bits;			} else 			     ops_size = 				get_sizeof(so_key->imme->imme_value) * 8;		}	} else if (so_key && do_key && !to_key) { 	/* two operands */		unsigned int reg_size = 0;		if (so_key->reg && do_key->reg) {			reg_size = get_reg_size(so_key->reg);			if (get_reg_size(do_key->reg) > reg_size)				reg_size = get_reg_size(do_key->reg);		} else if (so_key->reg) 			reg_size = get_reg_size(so_key->reg);		else if (do_key->reg) 			reg_size = get_reg_size(do_key->reg);		unsigned int mem_size = so_key->mem ? so_key->mem->cast : 			do_key->mem ? do_key->mem->cast : 0;		unsigned int imme_size = so_key->imme ? 			get_sizeof(so_key->imme->imme_value) * 8 : 			do_key->imme ? get_sizeof(do_key->imme->imme_value) * 8 				: 0; 				if (reg_size) {			if ((mem_size > reg_size) || (imme_size > reg_size))				ops_size = 0;			else				ops_size = reg_size;		} else if (mem_size) {			if (imme_size > mem_size)				ops_size = 0;			else 				ops_size = mem_size;		} else			ops_size = 0;	} else if (so_key && do_key && to_key) {	/* three operands */		ops_size = get_reg_size(to_key->reg);	}	return ops_size;}/******************************************************* the function get operands address size** last change: 02-18-2006 14:40 by mik******************************************************/unsigned int get_ops_addr(ops_key_t *ops_key){	unsigned int addr = 0;		if (!ops_key) return 0;	mem_t *mem = ops_key->so_key && ops_key->so_key->mem ?	 	ops_key->so_key->mem : ops_key->do_key && 		ops_key->do_key->mem ? ops_key->do_key->mem :		ops_key->to_key && ops_key->to_key->mem ? 		ops_key->to_key->mem : 0;	/*		if (mem) {		addr = mem->base ? (mem->base & 0xf0) >> 1 :			mem->index ? (mem->index & 0xf0) >> 1:			mem->disp ? get_sizeof(mem->disp) * 8 : 0;	}*/	addr = mem ? mem->addr : 0;	return addr;}/********************************************************* * the function check operand valid * * last change: 02-18-2006 14:15 by mik ********************************************************/int check_ops_key(ops_key_t *ops_key){	/* have no operand */	if (!ops_key)		return 1;		int ops_size = get_ops_size(ops_key);	int so_size = get_o_size(ops_key->so_key);	int do_size = get_o_size(ops_key->do_key);	int to_size = get_o_size(ops_key->to_key);	int addr = get_ops_addr(ops_key);	o_key_t *so_key = ops_key->so_key;	o_key_t *do_key = ops_key->do_key;	o_key_t *to_key = ops_key->to_key;	if ((ops_size >= 64) && (current_bits != 64))		return 0;	if ((addr >= 64) && (current_bits != 64))		return 0;	if ((so_key && is_eGPR(so_key->reg)) || (do_key && is_eGPR(do_key->reg))			|| (to_key && is_eGPR(to_key->reg)))		if (current_bits != 64)			return 0;	switch (get_ops_type(ops_key)) {	case D_R|S_R:		if (do_size < so_size)			return 0;		break;	case D_M|S_R:		if (do_size && (do_size != so_size))			return 0;		break;	case T_R|D_R|S_I:	/* this case for imul Gv, Ev, Iv */	case T_R|D_M|S_I:	case T_M|D_R|S_I:	/* this case for shld Ev,Gv,Ib */		if (to_size < do_size)			return 0;		break;	case T_M|D_R|S_R:		if (do_size < so_size || to_size < do_size)			return 0;		break;	}#if 0	if (ops_size && (ops_size <= current_bits) && (addr <= current_bits))	{		if ((current_bits == 64) && addr && (addr <= 16))				return 0;		return 1;	} else if ((current_bits == 16) && (ops_size < 64))		return 1;	#endif	return 1;}/*************************************************** follow for test....***************************************************/void release_o_key(o_key_t *o_key);void release_ops_key(ops_key_t *ops_key) {	if (ops_key->so_key) release_o_key(ops_key->so_key);	if (ops_key->do_key) release_o_key(ops_key->do_key);	if (ops_key->to_key) release_o_key(ops_key->to_key);}void release_o_key(o_key_t *o_key) {	if (o_key) {		if (o_key->mem)			free(o_key->mem);		free(o_key);	}	}/****************************************************************/void print_okey(o_key_t* o_key) {	printf("-----------------------------------\n");	printf("reg is %x\n", o_key->reg);	printf("imme is %f\n", o_key->imme);	union {		long long ll;		long l[2];	} l;	if (o_key->mem) {		printf("---base is %x\n", o_key->mem->base);		printf("---index is %x\n", o_key->mem->index);		printf("---scale is %x\n", o_key->mem->scale);		l.ll = o_key->mem->disp;			printf("---disp is %x\n", l.l[1]);		printf("---disp is %x\n", l.l[0]);		printf("---oseg is %x\n", o_key->mem->oseg);		printf("---cast is %d\n", o_key->mem->cast);		printf("---addr is %d\n", o_key->mem->addr);	}	printf("-----------------------------------------\n");}void print_ops(ops_key_t *ops) {	if (ops) {		if (ops->so_key) print_okey(ops->so_key);		if (ops->do_key) print_okey(ops->do_key);		if (ops->to_key) print_okey(ops->to_key);	}//	release_ops_key(ops);}void print_ops_attr(ops_attr_t *ops_attr){	printf("so_attr: %x\n", ops_attr->so_attr);	printf("do_attr: %x\n", ops_attr->do_attr);	printf("to_attr: %x\n", ops_attr->to_attr);}static void print_ekey(e_key_t *e_key){	while (e_key) {		print_ops(e_key->ops_key);		puts("**************************************");		e_key = e_key->next;	}}

⌨️ 快捷键说明

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