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