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