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

📄 nasm.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
                                       && (output_ins.oprs[0].type & COLON)
                                       && output_ins.oprs[0].segment ==
                                       NO_SEG
                                       && (output_ins.oprs[1].
                                           type & IMMEDIATE)
                                       && output_ins.oprs[1].segment ==
                                       NO_SEG) {
                                define_label(output_ins.label,
                                             output_ins.oprs[0].
                                             offset | SEG_ABS,
                                             output_ins.oprs[1].offset,
                                             NULL, false, false, ofmt,
                                             report_error);
                            } else
                                report_error(ERR_NONFATAL,
                                             "bad syntax for EQU");
                        }
                    }
                } else {        /* instruction isn't an EQU */

                    if (pass1 == 1) {

                        int64_t l = insn_size(location.segment, offs, sb, cpu,
                                           &output_ins, report_error);

                        /* if (using_debug_info)  && output_ins.opcode != -1) */
                        if (using_debug_info)
                        {       /* fbk 03/25/01 */
                            /* this is done here so we can do debug type info */
                            int32_t typeinfo =
                                TYS_ELEMENTS(output_ins.operands);
                            switch (output_ins.opcode) {
                            case I_RESB:
                                typeinfo =
                                    TYS_ELEMENTS(output_ins.oprs[0].
                                                 offset) | TY_BYTE;
                                break;
                            case I_RESW:
                                typeinfo =
                                    TYS_ELEMENTS(output_ins.oprs[0].
                                                 offset) | TY_WORD;
                                break;
                            case I_RESD:
                                typeinfo =
                                    TYS_ELEMENTS(output_ins.oprs[0].
                                                 offset) | TY_DWORD;
                                break;
                            case I_RESQ:
                                typeinfo =
                                    TYS_ELEMENTS(output_ins.oprs[0].
                                                 offset) | TY_QWORD;
                                break;
                            case I_REST:
                                typeinfo =
                                    TYS_ELEMENTS(output_ins.oprs[0].
                                                 offset) | TY_TBYTE;
                                break;
                            case I_RESO:
                                typeinfo =
                                    TYS_ELEMENTS(output_ins.oprs[0].
                                                 offset) | TY_OWORD;
                                break;
                            case I_RESY:
                                typeinfo =
                                    TYS_ELEMENTS(output_ins.oprs[0].
                                                 offset) | TY_YWORD;
                                break;
                            case I_DB:
                                typeinfo |= TY_BYTE;
                                break;
                            case I_DW:
                                typeinfo |= TY_WORD;
                                break;
                            case I_DD:
                                if (output_ins.eops_float)
                                    typeinfo |= TY_FLOAT;
                                else
                                    typeinfo |= TY_DWORD;
                                break;
                            case I_DQ:
                                typeinfo |= TY_QWORD;
                                break;
                            case I_DT:
                                typeinfo |= TY_TBYTE;
                                break;
			    case I_DO:
				typeinfo |= TY_OWORD;
				break;
			    case I_DY:
				typeinfo |= TY_YWORD;
				break;
                            default:
                                typeinfo = TY_LABEL;

                            }

                            ofmt->current_dfmt->debug_typevalue(typeinfo);

                        }
                        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 {
                        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);
        }

        if (passn > 1 && !global_offset_changed)
            pass0++;
        else if (global_offset_changed && global_offset_changed < prev_offset_changed) {
            prev_offset_changed = global_offset_changed;
            stall_count = 0;
            }
        else stall_count++;

        if((stall_count > 997) || (passn >= pass_max))
            /* We get here if the labels don't converge
             * Example: FOO equ FOO + 1
             */
             report_error(ERR_NONFATAL,
                          "Can't find valid values for all labels "
                          "after %d passes, giving up.\n"
                          "                  Possible cause: recursive equ's.", passn);
    }

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

static enum directives 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 (!nasm_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 (nasm_isspace(*buf))
            buf++;              /* beppu - skip leading whitespace */
        *value = buf;
        while (*buf != ']')
            buf++;
        *buf++ = '\0';
    }

    return bsii(*directive, directives, elements(directives));
}

/**
 * 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;
        int32_t lineno = 0;
        src_get(&lineno, &currentfile);
        fprintf(error_file, "%s:%"PRId32": ", 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;
        int32_t lineno = 0;
        src_get(&lineno, &currentfile);
        fprintf(error_file, "%s(%"PRId32") : ", 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 bool is_suppressed_warning(int severity)
{
    /*
     * See if it's a suppressed warning.
     */
    return (severity & ERR_MASK) == ERR_WARNING &&
	(((severity & ERR_WARN_MASK) != 0 &&
	  !warning_on[(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 != 1) ||
	 ((severity & ERR_PASS2) && 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|ERR_NO_SEVERITY)) {
    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;
    default:
	break;
    }

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

    if (severity & ERR_USAGE)
        want_usage = true;

    switch (severity & ERR_MASK) {
    case ERR_DEBUG:
        /* no further action, by definition */
        break;
    case ERR_WARNING:
	if (warning_on[0])	/* Treat warnings as errors */
	    terminate_after_phase = true;
	break;
    case ERR_NONFATAL:
        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 int32_t no_pp_lineinc;

static void no_pp_reset(char *file, int pass, efunc error, evalfunc eval,
                        ListGen * listgen, StrList **deplist)
{
    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,
         

⌨️ 快捷键说明

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