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

📄 nasmlib.c

📁 一个免费的汇编语言编译器的源代码
💻 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 256

static 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 + -