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

📄 nasm.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
                        if (l != -1) {
                           offs += l;
                           SET_CURR_OFFS (offs);
                        }
                        /*
                        * else l == -1 => invalid instruction, which will be
                        * flagged as an error on pass 2
                        */

                     } else { /* pass == 2 */
                        offs += assemble (location.segment, offs, sb, cpu,
                                       &output_ins, ofmt, report_error, &nasmlist);
                        SET_CURR_OFFS (offs);

                     }
               } /* not an EQU */
               cleanup_insn (&output_ins);
         }
         nasm_free (line);
         location.offset = offs = GET_CURR_OFFS;
      } /* end while (line = preproc->getline... */

      if (pass1==2 && global_offset_changed)
         report_error(ERR_NONFATAL, "phase error detected at end of assembly.");

      if (pass1 == 1) preproc->cleanup(1);

      if (pass1==1 && terminate_after_phase) {
         fclose(ofile);
         remove(outname);
         if (want_usage)
               usage();
         exit (1);
      }
      pass_cnt++;
      if (pass>1 && !global_offset_changed) {
   	 pass0++;
   	 if (pass0==2) pass = pass_max - 1;
      }	else if (!(optimizing>0)) pass0++;

   } /* for (pass=1; pass<=2; pass++) */

   preproc->cleanup(0);
   nasmlist.cleanup();
#if 1
   if (optimizing>0 && opt_verbose_info)	/*  -On and -Ov switches */
      fprintf(stdout,
                "info:: assembly required 1+%d+1 passes\n", pass_cnt-2);
#endif
} /* exit from assemble_file (...) */


static int getkw (char **directive, char **value)
{
    char *p, *q, *buf;
    
    buf = *directive;

    /*  allow leading spaces or tabs */
    while (*buf==' ' || *buf=='\t')
       buf++;

    if (*buf!='[')
    	return 0;

    p = buf;

    while (*p && *p != ']') p++;

    if (!*p)
	return 0;

    q = p++;

    while (*p && *p != ';') {
	if (!isspace(*p))
	    return 0;
	p++;
    }
    q[1] = '\0';

    *directive = p = buf+1;
    while (*buf && *buf!=' ' && *buf!=']' && *buf!='\t')
    	buf++;
    if (*buf==']') {
	*buf = '\0';
	*value = buf;
    } else {
	*buf++ = '\0';
        while (isspace(*buf)) buf++;   /* beppu - skip leading whitespace */
	*value = buf;
	while (*buf!=']') buf++;
	*buf++ = '\0';
    }
#if 0
    for (q=p; *q; q++)
	*q = tolower(*q);
#endif	
    if (!nasm_stricmp(p, "segment") || !nasm_stricmp(p, "section"))
    	return 1;
    if (!nasm_stricmp(p, "extern"))
    	return 2;
    if (!nasm_stricmp(p, "bits"))
    	return 3;
    if (!nasm_stricmp(p, "global"))
    	return 4;
    if (!nasm_stricmp(p, "common"))
    	return 5;
    if (!nasm_stricmp(p, "absolute"))
    	return 6;
    if (!nasm_stricmp(p, "debug"))
	return 7;
    if (!nasm_stricmp(p, "warning"))
    	return 8;
    if (!nasm_stricmp(p, "cpu"))
	return 9;
    if (!nasm_stricmp(p, "list"))    /* fbk 9/2/00 */
        return 10;
    return -1;
}

/**
 * gnu style error reporting
 * This function prints an error message to error_file in the
 * style used by GNU. An example would be:
 * file.asm:50: error: blah blah blah
 * where file.asm is the name of the file, 50 is the line number on 
 * which the error occurs (or is detected) and "error:" is one of
 * the possible optional diagnostics -- it can be "error" or "warning"
 * or something else.  Finally the line terminates with the actual 
 * error message.
 * 
 * @param severity the severity of the warning or error 
 * @param fmt the printf style format string
 */
static void report_error_gnu (int severity, const char *fmt, ...)
{
    va_list ap;

    if (is_suppressed_warning(severity))
	return;

    if (severity & ERR_NOFILE)
	fputs ("nasm: ", error_file);
    else {
	char * currentfile = NULL;
	long lineno = 0;
	src_get (&lineno, &currentfile);
	fprintf (error_file, "%s:%ld: ", currentfile, lineno);
	nasm_free (currentfile);
    }
    va_start (ap, fmt);
    report_error_common (severity, fmt, ap);
    va_end (ap);
}

/**
 * MS style error reporting
 * This function prints an error message to error_file in the
 * style used by Visual C and some other Microsoft tools. An example 
 * would be:
 * file.asm(50) : error: blah blah blah
 * where file.asm is the name of the file, 50 is the line number on 
 * which the error occurs (or is detected) and "error:" is one of
 * the possible optional diagnostics -- it can be "error" or "warning"
 * or something else.  Finally the line terminates with the actual 
 * error message.
 * 
 * @param severity the severity of the warning or error 
 * @param fmt the printf style format string
 */
static void report_error_vc (int severity, const char *fmt, ...)
{
    va_list ap;

    if (is_suppressed_warning (severity))
	return;

    if (severity & ERR_NOFILE)
	fputs ("nasm: ", error_file);
    else {
	char * currentfile = NULL;
	long lineno = 0;
	src_get (&lineno, &currentfile);
	fprintf (error_file, "%s(%ld) : ", currentfile, lineno);
	nasm_free (currentfile);
    }
    va_start (ap, fmt);
    report_error_common (severity, fmt, ap);
    va_end (ap);
}

/**
 * check for supressed warning
 * checks for suppressed warning or pass one only warning and we're 
 * not in pass 1
 *
 * @param severity the severity of the warning or error
 * @return true if we should abort error/warning printing
 */
static int is_suppressed_warning (int severity)
{
    /*
     * See if it's a suppressed warning.
     */
    return ((severity & ERR_MASK) == ERR_WARNING &&
	(severity & ERR_WARN_MASK) != 0 &&
	suppressed[ (severity & ERR_WARN_MASK) >> ERR_WARN_SHR ]) ||
    /*
     * See if it's a pass-one only warning and we're not in pass one.
     */
	((severity & ERR_PASS1) && pass0 == 2);
}

/**
 * common error reporting
 * This is the common back end of the error reporting schemes currently
 * implemented.  It prints the nature of the warning and then the 
 * specific error message to error_file and may or may not return.  It
 * doesn't return if the error severity is a "panic" or "debug" type.
 * 
 * @param severity the severity of the warning or error 
 * @param fmt the printf style format string
 */
static void report_error_common (int severity, const char *fmt, va_list args)
{
    switch (severity & ERR_MASK) {
      case ERR_WARNING:
	fputs ("warning: ", error_file); break;
      case ERR_NONFATAL:
	fputs ("error: ", error_file); break;
      case ERR_FATAL:
	fputs ("fatal: ", error_file); break;
      case ERR_PANIC:
	fputs ("panic: ", error_file); break;
      case ERR_DEBUG:
        fputs("debug: ", error_file); break;
    }

    vfprintf (error_file, fmt, args);
    fputc ('\n', error_file);

    if (severity & ERR_USAGE)
	want_usage = TRUE;

    switch (severity & ERR_MASK) {
      case ERR_WARNING: case ERR_DEBUG:
	/* no further action, by definition */
	break;
      case ERR_NONFATAL:
	/* hack enables listing(!) on errors */
        terminate_after_phase = TRUE;
	break;
      case ERR_FATAL:
	if (ofile) {
	    fclose(ofile);
	    remove(outname);
	}
	if (want_usage)
	    usage();
	exit(1);		       /* instantly die */
	break;			       /* placate silly compilers */
      case ERR_PANIC:
	fflush(NULL);
/*	abort();	*/	       /* halt, catch fire, and dump core */
	exit(3);
	break;
    }
}

static void usage(void)
{
    fputs("type `nasm -h' for help\n", error_file);
}

static void register_output_formats(void)
{
    ofmt = ofmt_register (report_error);
}

#define BUF_DELTA 512

static FILE *no_pp_fp;
static efunc no_pp_err;
static ListGen *no_pp_list;
static long no_pp_lineinc;

static void no_pp_reset (char *file, int pass, efunc error, evalfunc eval,
			 ListGen *listgen)
{
    src_set_fname(nasm_strdup(file));
    src_set_linnum(0);
    no_pp_lineinc = 1;
    no_pp_err = error;
    no_pp_fp = fopen(file, "r");
    if (!no_pp_fp)
	no_pp_err (ERR_FATAL | ERR_NOFILE,
		   "unable to open input file `%s'", file);
    no_pp_list = listgen;
    (void) pass;		       /* placate compilers */
    (void) eval;		       /* placate compilers */
}

static char *no_pp_getline (void)
{
    char *buffer, *p, *q;
    int bufsize;

    bufsize = BUF_DELTA;
    buffer = nasm_malloc(BUF_DELTA);
    src_set_linnum(src_get_linnum() + no_pp_lineinc);

    while (1) {   /* Loop to handle %line */

	p = buffer;
	while (1) {  /* Loop to handle long lines */
	    q = fgets(p, bufsize-(p-buffer), no_pp_fp);
	    if (!q)
		break;
	    p += strlen(p);
	    if (p > buffer && p[-1] == '\n')
		break;
	    if (p-buffer > bufsize-10) {
		int offset;
		offset = p - buffer;
		bufsize += BUF_DELTA;
		buffer = nasm_realloc(buffer, bufsize);
		p = buffer + offset;
	    }
	}

	if (!q && p == buffer) {
	    nasm_free (buffer);
	    return NULL;
	}

	/*
	 * Play safe: remove CRs, LFs and any spurious ^Zs, if any of
	 * them are present at the end of the line.
	 */
	buffer[strcspn(buffer, "\r\n\032")] = '\0';

	if (!strncmp(buffer, "%line", 5)) {
	    long ln;
	    int  li;
	    char *nm = nasm_malloc(strlen(buffer));
	    if (sscanf(buffer+5, "%ld+%d %s", &ln, &li, nm) == 3) {
		nasm_free( src_set_fname(nm) );
		src_set_linnum(ln);
		no_pp_lineinc = li;
		continue;
	    }
	    nasm_free(nm);
	}
	break;
    }

    no_pp_list->line (LIST_READ, buffer);

    return buffer;
}

static void no_pp_cleanup (int pass)
{
    fclose(no_pp_fp);
}

static unsigned long get_cpu (char *value)
{

    if (!strcmp(value, "8086")) return IF_8086;
    if (!strcmp(value, "186")) return IF_186;
    if (!strcmp(value, "286")) return IF_286;
    if (!strcmp(value, "386")) return IF_386;
    if (!strcmp(value, "486")) return IF_486;
    if (!strcmp(value, "586")    ||
    	!nasm_stricmp(value, "pentium") ) 	return IF_PENT;
    if (!strcmp(value, "686")  ||
    	!nasm_stricmp(value, "ppro") ||
    	!nasm_stricmp(value, "pentiumpro") ||
    	!nasm_stricmp(value, "p2")    ) 	return IF_P6;
    if (!nasm_stricmp(value, "p3")    ||
    	!nasm_stricmp(value, "katmai") ) 	return IF_KATMAI;
    if (!nasm_stricmp(value, "p4")    ||	/* is this right? -- jrc */
    	!nasm_stricmp(value, "willamette") ) 	return IF_WILLAMETTE;
    if (!nasm_stricmp(value, "prescott") )      return IF_PRESCOTT;
    if (!nasm_stricmp(value, "ia64") ||
	!nasm_stricmp(value, "ia-64") ||
	!nasm_stricmp(value, "itanium") ||
	!nasm_stricmp(value, "itanic") ||
	!nasm_stricmp(value, "merced") )	return IF_IA64;

    report_error (pass0<2 ? ERR_NONFATAL : ERR_FATAL, "unknown 'cpu' type");

    return IF_PLEVEL;	/* the maximum level */
}


static int get_bits (char *value)
{
    int i;

    if ((i = atoi(value)) == 16)  return i;   /* set for a 16-bit segment */
    else if (i == 32) {
	if (cpu < IF_386) {
	    report_error(ERR_NONFATAL,
	    	"cannot specify 32-bit segment on processor below a 386");
	    i = 16;
	}
    } else {
	report_error(pass0<2 ? ERR_NONFATAL : ERR_FATAL,
	   "`%s' is not a valid segment size; must be 16 or 32",
	   value);
	i = 16;
    }
    return i;
}

/* end of nasm.c */

⌨️ 快捷键说明

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