?? nasm.c
字號:
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, ¤tfile);
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, ¤tfile);
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 + -