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

📄 nasmlib.c

📁 支持AMD64的汇编编译器源码
💻 C
字号:
/* nasmlib.c	library routines for the Netwide Assembler * * The Netwide Assembler is copyright (C) 1996 Simon Tatham and * Julian Hall. All rights reserved. The software is * redistributable under the licence given in the file "Licence" * distributed in the NASM archive. */#include <util.h>#include <libyasm/coretype.h>#include <ctype.h>#include "nasm.h"#include "nasmlib.h"/*#include "insns.h"*/		/* For MAX_KEYWORD */#define lib_isnumchar(c)   ( isalnum(c) || (c) == '$')#define numvalue(c)  ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')long nasm_readnum (char *str, int *error) {    char *r = str, *q;    long radix;    unsigned long result, checklimit;    int digit, last;    int warn = FALSE;    int sign = 1;    *error = FALSE;    while (isspace(*r)) r++;	       /* find start of number */    /*     * If the number came from make_tok_num (as a result of an %assign), it     * might have a '-' built into it (rather than in a preceeding token).     */    if (*r == '-')    {	r++;	sign = -1;    }    q = r;    while (lib_isnumchar(*q)) q++;     /* find end of number */    /*     * If it begins 0x, 0X or $, or ends in H, it's in hex. if it     * ends in Q, it's octal. if it ends in B, it's binary.     * Otherwise, it's ordinary decimal.     */    if (*r=='0' && (r[1]=='x' || r[1]=='X'))	radix = 16, r += 2;    else if (*r=='$')	radix = 16, r++;    else if (q[-1]=='H' || q[-1]=='h')	radix = 16 , q--;    else if (q[-1]=='Q' || q[-1]=='q' || q[-1]=='O' || q[-1]=='o')	radix = 8 , q--;    else if (q[-1]=='B' || q[-1]=='b')	radix = 2 , q--;    else	radix = 10;    /*     * If this number has been found for us by something other than     * the ordinary scanners, then it might be malformed by having     * nothing between the prefix and the suffix. Check this case     * now.     */    if (r >= q) {	*error = TRUE;	return 0;    }    /*     * `checklimit' must be 2**32 / radix. We can't do that in     * 32-bit arithmetic, which we're (probably) using, so we     * cheat: since we know that all radices we use are even, we     * can divide 2**31 by radix/2 instead.     */    checklimit = 0x80000000UL / (radix>>1);    /*     * Calculate the highest allowable value for the last digit     * of a 32 bit constant... in radix 10, it is 6, otherwise it is 0     */    last = (radix == 10 ? 6 : 0);    result = 0;    while (*r && r < q) {	if (*r<'0' || (*r>'9' && *r<'A') || (digit = numvalue(*r)) >= radix) 	{	    *error = TRUE;	    return 0;	}	if (result > checklimit ||	    (result == checklimit && digit >= last))	{	    warn = TRUE;	}	result = radix * result + digit;	r++;    }#if 0    if (warn)	nasm_malloc_error (ERR_WARNING | ERR_PASS1 | ERR_WARN_NOV,			   "numeric constant %s does not fit in 32 bits",			   str);#endif    return result*sign;}long nasm_readstrnum (char *str, int length, int *warn) {    long charconst = 0;    int i;    *warn = FALSE;    str += length;    for (i=0; i<length; i++) {	if (charconst & 0xff000000UL) {	    *warn = TRUE;	}	charconst = (charconst<<8) + (unsigned char) *--str;    }    return charconst;}static long next_seg;void nasm_seg_init(void) {    next_seg = 0;}long nasm_seg_alloc(void) {    return (next_seg += 2) - 2;}/* * Return TRUE if the argument is a simple scalar. (Or a far- * absolute, which counts.) */int nasm_is_simple (nasm_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 nasm_is_really_simple (nasm_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 nasm_is_reloc (nasm_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 nasm_is_unknown(nasm_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 nasm_is_just_unknown(nasm_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 nasm_reloc_value (nasm_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 nasm_reloc_seg (nasm_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 nasm_reloc_wrt (nasm_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 nasm_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 *nasm_src_set_fname(char *newname) {    char *oldname = file_name;    file_name = newname;    return oldname;}long nasm_src_set_linnum(long newline) {    long oldline = line_number;    line_number = newline;    return oldline;}long nasm_src_get_linnum(void) {    return line_number;}int nasm_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) {    size_t 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;}

⌨️ 快捷键说明

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