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

📄 parse.c

📁 Intel x86处理器的汇编器
💻 C
字号:
#include "i_attribute.h"#include "a64-2.h"#include "parse.h"#include "error.h"#include "opcode.h"#include "iob.h"#include "label.h"#include <stdio.h>static char err_msg[80];static kw_id_t keyword_id = 0;void print_ekey();static errno_t parse_keyword(char *s);static errno_t parse_label(char *s);static struct return_struct do_parse_transfer(char *s, i_key_t *i_key);errno_t analyse_line(line_info_t *line_info, e_key_t *e_key, char *s) {	errno_t errno = 0;	char str[80];	int i = 0;	unsigned char c = 0;		if (!s || !s[0]) return ERR_LINE;	char *p = s;	/* i_key link */	i_key_t *i_key = 0;	ops_attr_t ops_attr = { 0, 0, 0 };	while (*p && ((*p == ' ') || (*p == KEY_TAB))) 			p++;		/* skip space or TAB */	while (*p && ((*p != ' ') && (*p != KEY_TAB))) 		str[i++] = *p++;			str[i] = 0;	if (c = get_prefixid(str)) {		/* this is a instruction prefix */			e_key->i_prefix = (prefix_t*)a64_malloc(sizeof(prefix_t));		e_key->i_prefix->lock = c == 0xf0 ? c : 0;		e_key->i_prefix->rep = c != 0xf0 ? c : 0;		i = 0;		while (*p && ((*p == ' ') || (*p == KEY_TAB))) 			p++;	/* skip ' ' */		/* get next instruction string */		while (*p && ((*p != ' ') && (*p != KEY_TAB)))			str[i++] = *p++;		str[i] = 0;	}	/* found instruction set */	if (!(i_key = (i_key_t *)get_ins(str))) {		mount_err_link(ERR_INS, line_errmsg, 0);		return ERR_INS; 	}	if (c) {		if (c == 0xf0) {	/* it's lock prefix */			/* do nothing */			} else if (!is_string_ins(i_key)) {	/* it's rep prefix */			/* example: rep movsb */			sprintf(err_msg, "at %d: invalid instruction \n", line);			mount_err_link(0, 0, err_msg);			return ERR_INS;		}	}next:		/* found instruction */		e_key->ops_key = (ops_key_t *)a64_malloc(sizeof(ops_key_t));	errno |= get_ops_key(e_key->ops_key, p);	/* check operands valid ??? */	if (!check_ops_key(e_key->ops_key)) {		sprintf(err_msg, "at %d: %s\n", line,			"check operands error, it's invalid operands");		mount_err_link(0, 0, err_msg);		return ERR_OPERAND;	}	get_ops_attr(&ops_attr,	e_key->ops_key);	o_key_t *so_key = e_key->ops_key->so_key;	o_key_t *do_key = e_key->ops_key->do_key;	mem_t *mem = so_key && so_key->mem ? so_key->mem :		do_key && do_key->mem ? do_key->mem : 0;		if (mem) {		if (mem->transfer_cast) {			if (((i_key == CALL) || (i_key == JMP)) && so_key->mem)				ops_attr.so_attr |= FAR_POINTER;			else {				sprintf(err_msg, 					"error at %d: error cast\n", line);				mount_err_link(0, 0, err_msg);				return ERR_ERROR;			}		}		}		if (!(e_key->i_key = get_i_key(i_key, &ops_attr))) {		sprintf(err_msg, "at %d: %s\n", line,			"invalid instruction or operands");		mount_err_link(0, 0, err_msg);					return ERR_INS;	}	/* check the instruct in current bits is valid ??? */	if (is_ONLY_IN_BITS(e_key->i_key->i_attr)) {		if (get_ONLY_BITS(e_key->i_key->i_attr) != current_bits) {			sprintf(err_msg, "error at %d: %s\n", line,				"instruct in current bits invalid");			mount_err_link(0, 0, err_msg);			return ERR_INS;		}	}			e_key->bits = current_bits;	return errno;}/********************************************************/static struct return_struct pre_analyse_line(char *s){	struct return_struct ret = { E_OK, s };		if (!s)		return ret;	char *p = s;	int i = 0;	char str[80];		errno_t errno = 0;	for ( ; ; p++) {		if (is_c(*p) || is_n(*p) || *p == '_') {			str[i++] = *p;			} else switch (*p) {		case 0 :			str[i] = 0;			if (ret.code == E_LABEL && i == 0) {				sprintf(err_msg, "error at %d: %s\n",					line, "label string error");				mount_err_link(0, 0, err_msg);				ret.code == E_ERROR;				return ret;			} else if (ret.code == E_KEYWORD && (i == 0)) {				ret.code = E_ERROR;			} else if (ret.code == E_NEED_CONON ||					((ret.code == E_LABEL) && i))			{				sprintf(err_msg, "error at %d: %s\n",					line, "label loss ':'");				mount_err_link(0, 0, err_msg);				ret.code = E_ERROR;				return ret;			} else if (ret.code == E_OK && i) {				/* keep E_OK for next step */				if (keyword_id = get_keyword(str)) {					ret.code = E_KEYWORD;					ret.ptr += i;				}			} else if (((ret.code == E_BLANK) || 					(ret.code == E_TAB)) && i) {				/** reserved for E_KEYWORD */				if (keyword_id = get_keyword(str)) {						ret.code = E_KEYWORD;					ret.ptr += i;				} else {					ret.code = E_OK;					ret.ptr = s;				}			} else 				ret.code = E_NEW_LINE;			goto do_parse_error;		case ' ':		case KEY_TAB:			if (i) {				str[i] = 0;				if (ret.code == E_KEYWORD) {					if (keyword_id = get_keyword(str)) {						ret.code = E_KEYWORD;						ret.ptr += i;					} else						ret.code = E_ERROR;					goto do_parse_error;				} else if ((ret.code == E_TAB) ||						(ret.code == E_BLANK)) {					i_key_t *i_key;					/* it's keyword ??? */					if (keyword_id = get_keyword(str)) {						ret.code = E_KEYWORD;						/* skip keyword string */						ret.ptr += i;					} 					else if (i_key=get_transfer_ins(str)) {						ret.ptr = p + 1;						ret = do_parse_transfer(								ret.ptr,i_key);												if (ret.code == E_OK)							ret.ptr = s;										} else						ret.code = E_OK;					goto do_parse_error;				} else if (ret.code == E_LABEL) {					/* it's label string */					/* next step do by E_CONON */					ret.code = E_NEED_CONON;					i = 0;				} else if (ret.code == E_NEED_CONON) {					sprintf(err_msg, "error at %d: %s \n",						line, "label loss ':'");					mount_err_link(0, 0, err_msg);					ret.code = E_ERROR;					return ret;				} else if (ret.code == E_CONON) {					/* parse label... 					   next step to do parse line....					*/					i_key_t *i_key = 0;					if (i_key = get_transfer_ins(str)) {						ret.ptr = p + 1;						ret = do_parse_transfer(							ret.ptr, i_key);						if (ret.code == E_OK)							ret.ptr = s;					} else {						ret.code = E_OK; 					}					goto do_parse_error;				} else if (ret.code == E_BLANK) {					if (keyword_id = get_keyword(str)) {						ret.code = E_KEYWORD;						ret.ptr += i;					} else						ret.code = E_OK;					goto do_parse_error;				} else if (ret.code == E_OK) {					i_key_t *i_key = 0;					if (keyword_id = get_keyword(str)) {						ret.code = E_KEYWORD;						ret.ptr += i;					} 					else if (i_key=get_transfer_ins(str))					{						ret.ptr = p + 1;						ret = do_parse_transfer(							ret.ptr, i_key);						if (ret.code == E_OK)							ret.ptr = s;						}					/* next step to do parse line... */					goto do_parse_error;				}			/* it's blank string...... */			} else {				if (ret.code == E_KEYWORD) {					/* it's keyword */					/* it's allow ". xxxx" */						break;				} else if (ret.code == E_LABEL) {					/* it's error */					sprintf(err_msg, "error at %d: %s\n",						line, "the label is error");					mount_err_link(0, 0, err_msg);					ret.code = E_ERROR;					goto do_parse_error;				} else if (ret.code == E_CONON) {					if (*p == ' ')						ret.code = E_BLANK;					else							ret.code = E_TAB;					ret.ptr = p + 1;				} else if (ret.code == E_NEED_CONON) {					/* keep the flag for label */				} else {					if (*p == ' ')						ret.code = E_BLANK;					else if (*p == KEY_TAB) 						ret.code = E_TAB;				}			}			ret.ptr = p + 1;			break;		case '.': 			/* it's a keyword */			if (i || ret.code == E_KEYWORD || ret.code == E_LABEL				|| ret.code == E_CONON)  {				ret.code = E_ERROR;				goto do_parse_error;			}			ret.code = E_KEYWORD;			ret.ptr = p + 1;			i = 0; break;		case '@':			/* it's a label */			if(i || ret.code == E_KEYWORD || ret.code == E_LABEL				|| ret.code == E_CONON) { 				ret.code = E_ERROR;				goto do_parse_error;			}			ret.code = E_LABEL;			ret.ptr = p + 1;			i = 0; break;		case ':':			if ((ret.code != E_LABEL) && (ret.code != E_NEED_CONON)) 			{				ret.code = E_ERROR;				goto do_parse_error;			}					if (ret.code != E_NEED_CONON)				str[i] = 0;			if (errno = parse_label(str)) {				mount_err_link(E_LABEL, line_errmsg, 0);				ret.code = E_ERROR;				return ret;			}			ret.code = E_CONON;			ret.ptr = p + 1;			i = 0; break;		case '!':			/* it's a comment */			ret.code = E_COMMENT;			return ret;		case '\n':			/* new line */			ret.code = E_NEW_LINE;			goto do_parse_error;		default: 			ret.code = E_ERROR;			goto do_parse_error;		}	}do_parse_error:	if (ret.code == E_ERROR) {		sprintf(err_msg, "error at line %d: %s '%c'\n",			line, "parse error at ", *p);		mount_err_link(0, 0, err_msg);	}	return ret;}/*************************************************************/static errno_t parse_label(char *s){	errno_t errno = 0;		if (!is_label(s))		mount_label_table(s);	else		errno = E_LABEL;	return errno;}static struct return_struct do_parse_transfer(char *p, i_key_t *i_key){	struct return_struct ret = { 0, p };	int i = 0;	char str[80];	while (*p && (*p == ' ' || *p == KEY_TAB))		p++;		if (*p == '@') {		p++;		while (*p && *p != ' ' && *p != KEY_TAB)			str[i++] = *p++;		str[i] = 0;		mount_hole_link(str, i_key);		ret.code = E_NEW_LINE;	} else {		/* this is a memory operand 		   example: jmp [ecx] */		ret.code = E_OK;	}	return ret;}/*************************************************************/static errno_t parse_keyword(char *s){	errno_t errno = 0;	char *p = s;	int i = 0;	char str[80];	while (*p && (*p == ' '|| *p == KEY_TAB))  			p++;	while (*p && *p != ' ' && *p != KEY_TAB)			str[i++] = *p++;	str[i] = 0;	while (*p && (*p == ' ' || *p == KEY_TAB)) p++;	switch (keyword_id) {	case KW_MODE:		current_mode = get_modeid(str);		if (!current_mode || *p) {			sprintf(err_msg, "error at %d: mode value error\n", 					line);			mount_err_link(0, 0, err_msg);			return ERR_ERROR;		}				break;	case KW_BITS:		current_bits = get_bitsid(str);		if (!current_bits || *p) {			sprintf(err_msg, "error at %d: bits value error\n",				line);			mount_err_link(0, 0, err_msg);			return ERR_ERROR;		}		break;	case KW_FUNCTION: 	/* it's function */		break;	case KW_VAR:		break;	case KW_CONST:		break;	case KW_CODE:		break;	case KW_TEXT:		break;	case KW_BYTE:		break;	case KW_WORD:		break;	case KW_DWORD:		break;	case KW_QWORD:		break;	case KW_MACRO:		break;	case KW_PTR:		break;	}	return errno;}/*********************************************************************//*static proceed_parse_keyword(char *s){}*//************************************************************************ function: analyse_file() paramter: void: return value: errno if error	************************************************************************/errno_t analyse_file(struct iob *iob){	errno_t errno = 0;	struct return_struct ret = { E_OK, 0 };	char linebuf[LINE_SIZE];	char err_msg[80];	e_key_t *head_e_key = e_key_link;	line_info_t line_info = { 0, 0 };			/* parse file */	while (read_into_iob(iob, sizeof(iob->buf))) {		/* parse line */		while (readln_from_iob(iob, linebuf)) {			line++; 						ret = pre_analyse_line(linebuf);			if (ret.code == E_ERROR) {				return ERR_OPERAND;			} else if (ret.code == E_KEYWORD) {				errno = parse_keyword(ret.ptr);				if (errno)						return ERR_OPERAND;					// goto do_analyse_file_error;				continue;			} else if (ret.code == E_BLANK) {			} else if (ret.code == E_NEW_LINE) {			} else if (ret.code == E_COMMENT) {			} else if (ret.code == E_OK) {				e_key_t *p = 					(e_key_t *)a64_malloc(sizeof(e_key_t));				p->line = line;				errno = analyse_line(&line_info, p, ret.ptr);				if (errno)					return errno;				if (!head_e_key) {						head_e_key = p;					e_key_link = p;	/* global e_key link */				} else {					while (head_e_key->next)						head_e_key = head_e_key->next;					head_e_key->next = p;				}							}			/* next line .... */		}	}do_analyse_file_error:	return errno;}/************************************************************************/void print_ekey(){	e_key_t *e_key = e_key_link;	while (e_key) {	#if 0		puts("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");		if (e_key->ops_key)			print_ops(e_key->ops_key);		if (e_key->i_key) {			printf("---i_attr: %x\n", e_key->i_key->i_attr);			printf("---opcode:%x\n", e_key->i_key->opcode);		}		if (e_key->i_prefix) {			printf("---lock: %x\n" ,e_key->i_prefix->lock);			printf("---rep: %x\n", e_key->i_prefix->rep);		}		puts("#############################");#endif		printf("e_key line is %d\n", e_key->line);		e_key = e_key->next;	}}/*char *testfile = "test.s";#include <fcntl.h>int main(){	struct iob riob, wiob;	int fd = open(testfile, O_RDONLY);	int fdw = open("kkk", O_CREAT);	init_iob(fd, &riob);	init_iob(fdw, &wiob);	char *e_buf = (char *)malloc(512);	errno_t errno = 0;	int i = 0;	errno = analyse_file(&riob);	if (errno) {		printf("%d\n",current_mode);		print_err();		exit(1);	}	if (errno = generate(&wiob)) {		print_err();		release_resource();		exit(1);	}		flush_all_iob(&wiob);#ifdef DEBUG_PRINT_CODE	while(i<current_pc) 	printf("%x ",(unsigned char)wiob.buf[i++]);	puts(""); #endif		release_resource();	close(fd);	close(fdw);	return 0;}*/

⌨️ 快捷键说明

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