📄 nasmlib.c
字号:
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 + -