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

📄 nasmlib.c

📁 开源的nasm编译器源码,研究编译器原理很有帮且
💻 C
📖 第 1 页 / 共 2 页
字号:
	    len -= l;	}	if (len > 0) {	    s->rptr = s->rptr->next;	    s->rpos = 0L;	}    }}void saa_fread (struct SAA *s, long posn, void *data, long len) {    struct SAA *p;    long pos;    char *cdata = data;    if (!s->rptr || posn < s->rptr->start)	saa_rewind (s);    p = s->rptr;    while (posn >= p->start + p->posn) {	p = p->next;	if (!p)	    return;		       /* what else can we do?! */    }    pos = posn - p->start;    while (len) {	long l = p->posn - pos;	if (l > len)	    l = len;	memcpy (cdata, p->data+pos, l);	len -= l;	cdata += l;	p = p->next;	if (!p)	    return;	pos = 0L;    }    s->rptr = p;}void saa_fwrite (struct SAA *s, long posn, void *data, long len) {    struct SAA *p;    long pos;    char *cdata = data;    if (!s->rptr || posn < s->rptr->start)	saa_rewind (s);    p = s->rptr;    while (posn >= p->start + p->posn) {	p = p->next;	if (!p)	    return;		       /* what else can we do?! */    }    pos = posn - p->start;    while (len) {	long l = p->posn - pos;	if (l > len)	    l = len;	memcpy (p->data+pos, cdata, l);	len -= l;	cdata += l;	p = p->next;	if (!p)	    return;	pos = 0L;    }    s->rptr = p;}void saa_fpwrite (struct SAA *s, FILE *fp) {    char *data;    long len;    saa_rewind (s);    while ( (data = saa_rbytes (s, &len)) )	fwrite (data, 1, len, fp);}/* * Register, instruction, condition-code and prefix keywords used * by the scanner. */#include "names.c"static const char *special_names[] = {    "byte", "dword", "far", "long", "near", "nosplit", "qword",    "short", "strict", "to", "tword", "word"};static const char *prefix_names[] = {    "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne",    "repnz", "repz", "times"};/* * Standard scanner routine used by parser.c and some output * formats. It keeps a succession of temporary-storage strings in * stdscan_tempstorage, which can be cleared using stdscan_reset. */static char **stdscan_tempstorage = NULL;static int stdscan_tempsize = 0, stdscan_templen = 0;#define STDSCAN_TEMP_DELTA 256static void stdscan_pop(void) {    nasm_free (stdscan_tempstorage[--stdscan_templen]);}void stdscan_reset(void) {    while (stdscan_templen > 0)	stdscan_pop();}/* * Unimportant cleanup is done to avoid confusing people who are trying * to debug real memory leaks */void nasmlib_cleanup (void) {    stdscan_reset();    nasm_free (stdscan_tempstorage);}static char *stdscan_copy(char *p, int len) {    char *text;    text = nasm_malloc(len+1);    strncpy (text, p, len);    text[len] = '\0';    if (stdscan_templen >= stdscan_tempsize) {	stdscan_tempsize += STDSCAN_TEMP_DELTA;	stdscan_tempstorage = nasm_realloc(stdscan_tempstorage,					   stdscan_tempsize*sizeof(char *));    }    stdscan_tempstorage[stdscan_templen++] = text;    return text;}char *stdscan_bufptr = NULL;int stdscan (void *private_data, struct tokenval *tv) {    char ourcopy[MAX_KEYWORD+1], *r, *s;    (void) private_data;  /* Don't warn that this parameter is unused */    while (isspace(*stdscan_bufptr)) stdscan_bufptr++;    if (!*stdscan_bufptr)	return tv->t_type = 0;    /* we have a token; either an id, a number or a char */    if (isidstart(*stdscan_bufptr) ||	(*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) {	/* now we've got an identifier */	int i;	int is_sym = FALSE;	if (*stdscan_bufptr == '$') {	    is_sym = TRUE;	    stdscan_bufptr++;	} 	r = stdscan_bufptr++;	/* read the entire buffer to advance the buffer pointer but... */	while (isidchar(*stdscan_bufptr)) stdscan_bufptr++;	/* ... copy only up to IDLEN_MAX-1 characters */	tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r < IDLEN_MAX ? 		stdscan_bufptr - r : IDLEN_MAX - 1);	if (is_sym || stdscan_bufptr-r > MAX_KEYWORD)	    return tv->t_type = TOKEN_ID;/* bypass all other checks */    	for (s=tv->t_charptr, r=ourcopy; *s; s++)	    *r++ = tolower (*s);	*r = '\0';	/* right, so we have an identifier sitting in temp storage. now,	 * is it actually a register or instruction name, or what? */	if ((tv->t_integer=bsi(ourcopy, reg_names,			       elements(reg_names)))>=0) {	    tv->t_integer += EXPR_REG_START;	    return tv->t_type = TOKEN_REG;	} else if ((tv->t_integer=bsi(ourcopy, insn_names,				      elements(insn_names)))>=0) {	    return tv->t_type = TOKEN_INSN;	}	for (i=0; i<elements(icn); i++)	    if (!strncmp(ourcopy, icn[i], strlen(icn[i]))) {		char *p = ourcopy + strlen(icn[i]);		tv->t_integer = ico[i];		if ((tv->t_inttwo=bsi(p, conditions,					 elements(conditions)))>=0)		    return tv->t_type = TOKEN_INSN;	    }	if ((tv->t_integer=bsi(ourcopy, prefix_names,				  elements(prefix_names)))>=0) {	    tv->t_integer += PREFIX_ENUM_START;	    return tv->t_type = TOKEN_PREFIX;	}	if ((tv->t_integer=bsi(ourcopy, special_names,				  elements(special_names)))>=0)	    return tv->t_type = TOKEN_SPECIAL;	if (!nasm_stricmp(ourcopy, "seg"))	    return tv->t_type = TOKEN_SEG;	if (!nasm_stricmp(ourcopy, "wrt"))	    return tv->t_type = TOKEN_WRT;	return tv->t_type = TOKEN_ID;    } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) {	/*	 * It's a $ sign with no following hex number; this must	 * mean it's a Here token ($), evaluating to the current	 * assembly location, or a Base token ($$), evaluating to	 * the base of the current segment.	 */	stdscan_bufptr++;	if (*stdscan_bufptr == '$') {	    stdscan_bufptr++;	    return tv->t_type = TOKEN_BASE;	}	return tv->t_type = TOKEN_HERE;    } else if (isnumstart(*stdscan_bufptr)) {  /* now we've got a number */	int rn_error;	r = stdscan_bufptr++;	while (isnumchar(*stdscan_bufptr))	    stdscan_bufptr++;	if (*stdscan_bufptr == '.') {	    /*	     * a floating point constant	     */	    stdscan_bufptr++;	    while (isnumchar(*stdscan_bufptr) ||		   ((stdscan_bufptr[-1] == 'e' || stdscan_bufptr[-1] == 'E')		    && (*stdscan_bufptr == '-' || *stdscan_bufptr == '+')) ) 	    {		stdscan_bufptr++;	    }	    tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r);	    return tv->t_type = TOKEN_FLOAT;	}	r = stdscan_copy(r, stdscan_bufptr - r);	tv->t_integer = readnum(r, &rn_error);	stdscan_pop();	if (rn_error)	    return tv->t_type = TOKEN_ERRNUM;/* some malformation occurred */	tv->t_charptr = NULL;	return tv->t_type = TOKEN_NUM;    } else if (*stdscan_bufptr == '\'' ||	       *stdscan_bufptr == '"') {/* a char constant */    	char quote = *stdscan_bufptr++, *r;	int rn_warn;	r = tv->t_charptr = stdscan_bufptr;	while (*stdscan_bufptr && *stdscan_bufptr != quote) stdscan_bufptr++;	tv->t_inttwo = stdscan_bufptr - r;      /* store full version */	if (!*stdscan_bufptr)	    return tv->t_type = TOKEN_ERRNUM;       /* unmatched quotes */	stdscan_bufptr++;			/* skip over final quote */	tv->t_integer = readstrnum(r, tv->t_inttwo, &rn_warn);	/* FIXME: rn_warn is not checked! */	return tv->t_type = TOKEN_NUM;    } else if (*stdscan_bufptr == ';') {  /* a comment has happened - stay */	return tv->t_type = 0;    } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '>') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_SHR;    } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '<') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_SHL;    } else if (stdscan_bufptr[0] == '/' && stdscan_bufptr[1] == '/') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_SDIV;    } else if (stdscan_bufptr[0] == '%' && stdscan_bufptr[1] == '%') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_SMOD;    } else if (stdscan_bufptr[0] == '=' && stdscan_bufptr[1] == '=') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_EQ;    } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '>') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_NE;    } else if (stdscan_bufptr[0] == '!' && stdscan_bufptr[1] == '=') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_NE;    } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '=') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_LE;    } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '=') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_GE;    } else if (stdscan_bufptr[0] == '&' && stdscan_bufptr[1] == '&') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_DBL_AND;    } else if (stdscan_bufptr[0] == '^' && stdscan_bufptr[1] == '^') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_DBL_XOR;    } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') {	stdscan_bufptr += 2;	return tv->t_type = TOKEN_DBL_OR;    } else			       /* just an ordinary char */    	return tv->t_type = (unsigned char) (*stdscan_bufptr++);}/* * Return TRUE if the argument is a simple scalar. (Or a far- * absolute, which counts.) */int is_simple (expr *vect) {    while (vect->type && !vect->value)    	vect++;    if (!vect->type)	return 1;    if (vect->type != EXPR_SIMPLE)	return 0;    do {	vect++;    } while (vect->type && !vect->value);    if (vect->type && vect->type < EXPR_SEGBASE+SEG_ABS) return 0;    return 1;}/* * Return TRUE if the argument is a simple scalar, _NOT_ a far- * absolute. */int is_really_simple (expr *vect) {    while (vect->type && !vect->value)    	vect++;    if (!vect->type)	return 1;    if (vect->type != EXPR_SIMPLE)	return 0;    do {	vect++;    } while (vect->type && !vect->value);    if (vect->type) return 0;    return 1;}/* * Return TRUE if the argument is relocatable (i.e. a simple * scalar, plus at most one segment-base, plus possibly a WRT). */int is_reloc (expr *vect) {    while (vect->type && !vect->value) /* skip initial value-0 terms */    	vect++;    if (!vect->type)		       /* trivially return TRUE if nothing */	return 1;		       /* is present apart from value-0s */    if (vect->type < EXPR_SIMPLE)      /* FALSE if a register is present */	return 0;    if (vect->type == EXPR_SIMPLE) {   /* skip over a pure number term... */	do {	    vect++;	} while (vect->type && !vect->value);	if (!vect->type)	       /* ...returning TRUE if that's all */	    return 1;    }    if (vect->type == EXPR_WRT) {      /* skip over a WRT term... */	do {	    vect++;	} while (vect->type && !vect->value);	if (!vect->type)	       /* ...returning TRUE if that's all */	    return 1;    }    if (vect->value != 0 && vect->value != 1)	return 0;		       /* segment base multiplier non-unity */    do {			       /* skip over _one_ seg-base term... */	vect++;    } while (vect->type && !vect->value);    if (!vect->type)		       /* ...returning TRUE if that's all */	return 1;    return 0;			       /* And return FALSE if there's more */}/* * Return TRUE if the argument contains an `unknown' part. */int is_unknown(expr *vect) {    while (vect->type && vect->type < EXPR_UNKNOWN)	vect++;    return (vect->type == EXPR_UNKNOWN);}/* * Return TRUE if the argument contains nothing but an `unknown' * part. */int is_just_unknown(expr *vect) {    while (vect->type && !vect->value)	vect++;    return (vect->type == EXPR_UNKNOWN);}/* * Return the scalar part of a relocatable vector. (Including * simple scalar vectors - those qualify as relocatable.) */long reloc_value (expr *vect) {    while (vect->type && !vect->value)    	vect++;    if (!vect->type) return 0;    if (vect->type == EXPR_SIMPLE)	return vect->value;    else	return 0;}/* * Return the segment number of a relocatable vector, or NO_SEG for * simple scalars. */long reloc_seg (expr *vect) {    while (vect->type && (vect->type == EXPR_WRT || !vect->value))    	vect++;    if (vect->type == EXPR_SIMPLE) {	do {	    vect++;	} while (vect->type && (vect->type == EXPR_WRT || !vect->value));    }    if (!vect->type)	return NO_SEG;    else	return vect->type - EXPR_SEGBASE;}/* * Return the WRT segment number of a relocatable vector, or NO_SEG * if no WRT part is present. */long reloc_wrt (expr *vect) {    while (vect->type && vect->type < EXPR_WRT)    	vect++;    if (vect->type == EXPR_WRT) {	return vect->value;    } else	return NO_SEG;}/* * Binary search. */int bsi (char *string, const char **array, int size) {    int i = -1, j = size;	       /* always, i < index < j */    while (j-i >= 2) {	int k = (i+j)/2;	int l = strcmp(string, array[k]);	if (l<0)		       /* it's in the first half */	    j = k;	else if (l>0)		       /* it's in the second half */	    i = k;	else			       /* we've got it :) */	    return k;    }    return -1;			       /* we haven't got it :( */}static char *file_name = NULL;static long line_number = 0;char *src_set_fname(char *newname) {    char *oldname = file_name;    file_name = newname;    return oldname;}long src_set_linnum(long newline) {    long oldline = line_number;    line_number = newline;    return oldline;}long src_get_linnum(void) {    return line_number;}int src_get(long *xline, char **xname) {    if (!file_name || !*xname || strcmp(*xname, file_name))     {	nasm_free(*xname);	*xname = file_name ? nasm_strdup(file_name) : NULL;	*xline = line_number;	return -2;    }    if (*xline != line_number)     {	long tmp = line_number - *xline;	*xline = line_number;	return tmp;    }    return 0;}void nasm_quote(char **str) {    int ln=strlen(*str);    char q=(*str)[0];    char *p;    if (ln>1 && (*str)[ln-1]==q && (q=='"' || q=='\''))	return;    q = '"';    if (strchr(*str,q))	q = '\'';    p = nasm_malloc(ln+3);    strcpy(p+1, *str);    nasm_free(*str);    p[ln+1] = p[0] = q;    p[ln+2] = 0;    *str = p;}    char *nasm_strcat(char *one, char *two) {    char *rslt;    int l1=strlen(one);    rslt = nasm_malloc(l1+strlen(two)+1);    strcpy(rslt, one);    strcpy(rslt+l1, two);    return rslt;}void null_debug_init(struct ofmt *of, void *id, FILE *fp, efunc error ) {}void null_debug_linenum(const char *filename, long linenumber, long segto) {}void null_debug_deflabel(char *name, long segment, long offset, int is_global, char *special) {}void null_debug_routine(const char *directive, const char *params) {}void null_debug_typevalue(long type) {}void null_debug_output(int type, void *param) {}void null_debug_cleanup(void){}struct dfmt null_debug_form = {    "Null debug format",    "null",    null_debug_init,    null_debug_linenum,    null_debug_deflabel,    null_debug_routine,    null_debug_typevalue,    null_debug_output,    null_debug_cleanup};struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };

⌨️ 快捷键说明

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