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

📄 operand.c

📁 Intel x86处理器的汇编器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * **/#include "a64-2.h"#include "operand.h"#include "error.h"#include "label.h"#include <stdio.h>int is_variable(char *s){	return 0;}/*********************************************************  example:  parameter: s = "(dword)es:[eax+ecx*8+0xc]" (one operand)	    o_key = get a operand's key word return value: error if errno is set	       successed if errno is 0last change: 02-17-2006 21:24 by miklast change: 02-19-2006 21:05 by mik**********************************************************/errno_t get_o_key(o_key_t *o_key, char *s) {	if (!s || !s[0]) return 0;	errno_t errno = 0; 	/* return value */	char *p = s;	char str[80];	int i = 0;	unsigned char c = 0;	if (!o_key) 		return ERR_OPERAND;	/* the operand is a memory operand */	if (get_c(s, '[') == 1)		o_key->mem = (mem_t *)a64_malloc(sizeof(mem_t));		 	/* parse operand 	 *	 * for example: (dword)es:[ecx*8+eax+0xc]	 */	char tmp_msg[120];	char *msg = get_err_msg_addr();	while (*p) {		if (is_c(*p) || is_n(*p)) {			str[i++] = *p;		} else switch (*p) {		case '(':			if (p != s) {	/* it's not head */ 				sprintf(tmp_msg, "at %d: %s\n", line,					"parse error at before '('");					if (str_len(msg) + str_len(tmp_msg) 					< ERR_MSG_SIZE) 				{					str_cat(msg, tmp_msg);				}			}			if (get_c(s,')') != 1) 				errno |= ERR_SLBRACKET;			i = 0; break;		case ')':			/* get operand size cast value */			if (get_c(s, '(') != 1) 				errno |= ERR_SRBRACKET;					str[i] = 0;			unsigned char cast = get_castid(str);			if (!check_cast(cast))				errno |= ERR_CAST;			if (o_key->mem) {				if (cast == NEAR_ID || cast == FAR_ID)					o_key->mem->transfer_cast = cast;				else 					/* it's a memory cast */					o_key->mem->cast = cast;			} else {				/* it's a immediate cast */				o_key->imme = 					(imme_t *)a64_malloc(sizeof(mem_t));				o_key->imme->cast = cast;			}						i = 0; break;		case ':':	/* segment override */			/* get segment override size byte */			str[i] = 0;			o_key->mem->oseg = get_osegid(str);			if (!check_oseg(o_key->mem->oseg)) {				if (current_bits == 64) {					sprintf(tmp_msg, "error at %d: %s\n",						line, "in 64-bit mode: the "						"prefix illegal! ");					mount_err_link(0, 0, tmp_msg);					errno |= ERR_ERROR;				} else 					errno |= ERR_PREFIX;			}			i = 0; break;		case '[':		/* memory operand */			/*******************************			 TO DO: this is reserved for var ....			 example: var1[eax]			 this is same as [eax + var1]			*****************************/		#ifdef RESERVED_VAR			str[i] = 0;			/* check var at var table */			if (!check_var(str)) 				errno |= ERR_OPERAND;			p++; 	/* skip '[' */		#else			/* xxx[...] is error */			if (i) errno |= ERR_OPERAND;		#endif			if (get_c(s, ']') != 1) 				errno |= ERR_MRBRACKET;					i = 0; break;		case '+':		case ']':			if (*p == ']') {				if (get_c(s, '[') != 1) 					errno |= ERR_MLBRACKET;				if ((*(p+1) != 0) && (*(p+1) != '!')) {						/* not tail and not comment */					/* errno |= ERR_OPERAND; */					sprintf(tmp_msg, "at %d: %s\n",						line, 						"parse error at after ']'");					if (str_len(msg) + str_len(tmp_msg)						< ERR_MSG_SIZE)					{						str_cat(msg, tmp_msg);						}				}			}			str[i] = 0;			c = get_regid(str);			if (check_mreg(c)) {	/* it's valid register */				if (!o_key->mem->base) 					o_key->mem->base = c;				else if (!o_key->mem->index) 					o_key->mem->index = c;				else					errno |= ERR_BASE;					/* check base register and index register */				if (o_key->mem->base && o_key->mem->index)					if ((o_key->mem->base & 0xf0) !=						(o_key->mem->index & 0xf0))						errno |= ERR_BASE;			/* this is a disp value or scale value */			} else if (is_numeric(str)) {				if (is_n(*(p-1)) && (*(p-2) == '*')) {					/* scale value */					o_key->mem->scale = get_scaleid(str);					if (!o_key->mem->scale)						errno |= ERR_SCALE;				} else if (!o_key->mem->disp) {					/* displacement value */					o_key->mem->disp = str_to_n(str);				} else 					errno |= ERR_DISP;			} else 	{ /* illegal operand */				/* errno |= ERR_OPERAND; */				sprintf(tmp_msg, "at %d: parse error at %s\n",					line, str); 				if (str_len(msg) + str_len(tmp_msg)					< ERR_MSG_SIZE)				{					str_cat(msg, tmp_msg);				}			}					i = 0; break;		case '-':			str[i] = 0;			c = get_regid(str);			if (check_mreg(c)) {	/* valid regiser */				if (!o_key->mem->base) 					o_key->mem->base = c;				else if (!o_key->mem->index) 					o_key->mem->index = c;				else 					errno |= ERR_BASE;				if (o_key->mem->base && o_key->mem->index)					if ((o_key->mem->base & 0xf0) !=						(o_key->mem->index & 0xf0))						errno != ERR_BASE;					/*********************************** 			 * TODO: reserved for disp or scale value 			 ***********************************/			} else {				/* errno |= ERR_OPERAND; */				sprintf(tmp_msg, "at %d: parse error at %s\n",					line, str);				if (str_len(msg) + str_len(tmp_msg)						< ERR_MSG_SIZE) 					str_cat(msg, tmp_msg);			}						/***************************************/			char *tp = p + 1;			i = 0;			while (*tp && *tp != ']')				str[i++] = *tp++;			str[i] = 0;			if (is_numeric(str) && (!o_key->mem->disp)) 					o_key->mem->disp = -str_to_n(str);			else 				return errno | ERR_OPERAND;						p = tp;				i = 0; break;		case '*':			/* it's a index register */			str[i] = 0;			c = get_regid(str);			if (check_mreg(c) && !o_key->mem->index) {				/* it's index register */				o_key->mem->index = c;				if (o_key->mem->base && 					((o_key->mem->base & 0xf0) !=					(o_key->mem->index & 0xf0)))					errno |= ERR_BASE;			} else 				errno |= ERR_INDEX;						i = 0; break;		case '@':  			/* it's a label string */					if (i) errno |= ERR_OPERAND;/*			while (*p != ' ')				str[i++] = *p++;				str[i] = 0;*/						/****************			 *	mount_hole_link()			 ***************/						i = 0; break;		case 0x09: 			/* it's a tab */			i = 0; break;		case '!':			while (*p) p++;			continue;		default:			errno |= ERR_CHARACTER;		}			p++;	}		if (errno || str_len(msg)) {		if (str_len(msg) == 0) {			sprintf(msg, "at %d: ", line);		}			mount_err_link(errno, ops_errmsg, msg);		goto do_error;	}	str[i] = 0;	if (o_key->mem) {				/* memory operand */		mem_t *mem = o_key->mem;		/* check base register invalid */		/* example: [esp*4+ecx]	is invalid */		if (((mem->index == ESP) || (mem->index == RSP)) && mem->scale) 		{			sprintf(msg, "at %d: %s\n",				line,				"When index register is \"sp\"" 				"the scale value error");			mount_err_link(0, 0, msg);			/* errno |= ERR_BASE; */			goto do_error;		}			/**** check 16-bit address size ****/		/*		  In 16-bit address size mode:	          [bx+bp] or [si+di] are error		*/		if (((mem->base == BX) && (mem->index == BP))			|| ((mem->base == SI) && (mem->index == DI)))		{			errno |= ERR_BASE;			mount_err_link(errno, ops_errmsg, 0);			goto do_error;		}		if (mem->disp) {			/* the disp example: [eax+0x0808004] */			/* example: disp is 8bytes and size is 32bit */			if (get_sizeof(o_key->mem->disp) > 					(current_bits >> 3)) 			{				union {					long long ll; /* 64-bit */					short word;   /* 16-bit */					int dword;    /* 32-bit */				} u;				u.ll = o_key->mem->disp;				switch (current_bits) {				case 16:					o_key->mem->disp = u.word;					break;				case 32:					o_key->mem->disp = u.dword;					break;				}			}					} /* if: disp */		if (o_key->mem->base)			o_key->mem->addr = (o_key->mem->base & 0xf0) >> 1;		else if (o_key->mem->index)			o_key->mem->addr = (o_key->mem->index & 0xf0) >> 1;/*		else			o_key->mem->addr = current_bits;*/				return errno;	} else if (o_key->reg = get_regid(str)) {	/* register operand */		/********************		 TODO: check_reg()                ********************/				} else if (is_numeric(str)) {			/* immedeate operand */		/*******************		TODO: check_imme()                ********************/		if (!o_key->imme)			o_key->imme = (imme_t *)a64_malloc(sizeof(imme_t));		o_key->imme->imme_value = (long long)str_to_n(str); /*		union{			long l[2];			long long ll;		}u;		u.ll = o_key->imme->imme_value;		printf("--%x%x--\n",u.l[1],u.l[0]);*/		unsigned int imme_size = 0;		if (o_key->imme->cast > current_bits)			errno |= ERR_CAST;		else if (o_key->imme->cast)			imme_size = o_key->imme->cast; 		else			o_key->imme->cast = 				get_sizeof(o_key->imme->imme_value) * 8;#if 0		else if (get_sizeof(o_key->imme->imme_value) > 					(current_bits >> 3)) 		{			imme_size = current_bits;		}				if (imme_size) {			union {				long long ll;				int dword;				short word;			} u;			u.ll = o_key->imme->imme_value;			switch (current_bits) {			case 16:				o_key->imme->imme_value = u.word;				break;			case 32: 				o_key->imme->imme_value = u.dword;			}		}#endif	} else if (is_label(str)) {		/* this is a label for "jmp" or "call" */	} else if (is_variable(str)) { /* is a variable value */		/**********************************                 * TODO: reserved for is_variable()		 *********************************/	} else {		errno |= ERR_OPERAND;		mount_err_link(errno, ops_errmsg, 0);	}	do_error:	/* it's not memory operand, so free o_key->mem */	if (o_key->mem) {		a64_free(o_key->mem);		o_key->mem = 0;	}	return errno;}/************************************************************* example: parameter: s = "eax,(dword)es:[eax+ecx*8+0xc]"	    ops_key = get the ops_key_t value for parameter s;	 return value:  error if errno value is set		succssed if errno is 0last change: 02-18-2006 14:20 by mik**************************************************************/errno_t get_ops_key(ops_key_t *ops_key, char *s) {	/* have no operands */	if (!s || !*s) return 0;	int i = 0;	char str[80];	char trims[200];	errno_t errno = 0;	/* return value */			if (!trim_space(trims, s) || !ops_key)		return ERR_OPERAND;	s = trims;	char *p = s + str_len(s) - 1;	char *q = s;		char tmp_msg[80];	char *msg = get_err_msg_addr();	/* find operands and get operand key word */	while (*p) {		q = p;		while (*p != ',') {		/* search last ',' */			if (p <= s) break;			p--;		}		i = 0;		if (*p == ',') {			while (p+i+1 <= q) {

⌨️ 快捷键说明

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