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

📄 nasm.c

📁 32位汇编编译器nasm源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    p = args;
    if (*p && *p != '-')
        separator = *p++;
    arg = NULL;
    while (*p) {
        q = p;
        while (*p && *p != separator)
            p++;
        while (*p == separator)
            *p++ = '\0';
        prevarg = arg;
        arg = q;
        if (process_arg(prevarg, arg))
            arg = NULL;
    }
    if (arg)
        process_arg(arg, NULL);
}

static void parse_cmdline(int argc, char **argv)
{
    FILE *rfile;
    char *envreal, *envcopy = NULL, *p, *arg;

    *inname = *outname = *listname = '\0';

    /*
     * First, process the NASMENV environment variable.
     */
    envreal = getenv("NASMENV");
    arg = NULL;
    if (envreal) {
        envcopy = nasm_strdup(envreal);
        process_args(envcopy);
        nasm_free(envcopy);
    }

    /*
     * Now process the actual command line.
     */
    while (--argc) {
        int i;
        argv++;
        if (argv[0][0] == '@') {
            /* We have a response file, so process this as a set of
             * arguments like the environment variable. This allows us
             * to have multiple arguments on a single line, which is
             * different to the -@resp file processing below for regular
             * NASM.
             */
            char *str = malloc(2048);
            FILE *f = fopen(&argv[0][1], "r");
            if (!str) {
                printf("out of memory");
                exit(-1);
            }
            if (f) {
                while (fgets(str, 2048, f)) {
                    process_args(str);
                }
                fclose(f);
            }
            free(str);
            argc--;
            argv++;
        }
        if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') {
            if ((p = get_param(argv[0], argc > 1 ? argv[1] : NULL, &i))) {
                if ((rfile = fopen(p, "r"))) {
                    process_respfile(rfile);
                    fclose(rfile);
                } else
                    report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
                                 "unable to open response file `%s'", p);
            }
        } else
            i = process_arg(argv[0], argc > 1 ? argv[1] : NULL);
        argv += i, argc -= i;
    }

    if (!*inname)
        report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
                     "no input file specified");
}

static void assemble_file(char *fname)
{
    char *directive, *value, *p, *q, *special, *line, debugid[80];
    insn output_ins;
    int i, rn_error, validid;
    long seg, offs;
    struct tokenval tokval;
    expr *e;
    int pass, pass_max;
    int pass_cnt = 0;           /* count actual passes */

    if (cmd_sb == 32 && cmd_cpu < IF_386)
        report_error(ERR_FATAL, "command line: "
                     "32-bit segment size requires a higher cpu");

    pass_max = (optimizing > 0 ? optimizing : 0) + 2;   /* passes 1, optimizing, then 2 */
    pass0 = !(optimizing > 0);  /* start at 1 if not optimizing */
    for (pass = 1; pass <= pass_max && pass0 <= 2; pass++) {
        int pass1, pass2;
        ldfunc def_label;

        pass1 = pass < pass_max ? 1 : 2;        /* seq is 1, 1, 1,..., 1, 2 */
        pass2 = pass > 1 ? 2 : 1;       /* seq is 1, 2, 2,..., 2, 2 */
        /*      pass0                            seq is 0, 0, 0,..., 1, 2 */

        def_label = pass > 1 ? redefine_label : define_label;

        sb = cmd_sb;            /* set 'bits' to command line default */
        cpu = cmd_cpu;
        if (pass0 == 2) {
            if (*listname)
                nasmlist.init(listname, report_error);
        }
        in_abs_seg = FALSE;
        global_offset_changed = FALSE;  /* set by redefine_label */
        location.segment = ofmt->section(NULL, pass2, &sb);
        if (pass > 1) {
            saa_rewind(forwrefs);
            forwref = saa_rstruct(forwrefs);
            raa_free(offsets);
            offsets = raa_init();
        }
        preproc->reset(fname, pass1, report_error, evaluate, &nasmlist);
        globallineno = 0;
        if (pass == 1)
            location.known = TRUE;
        location.offset = offs = GET_CURR_OFFS;

        while ((line = preproc->getline())) {
            globallineno++;

            /* here we parse our directives; this is not handled by the 'real'
             * parser. */
            directive = line;
            if ((i = getkw(&directive, &value))) {
                switch (i) {
                case 1:        /* [SEGMENT n] */
                    seg = ofmt->section(value, pass2, &sb);
                    if (seg == NO_SEG) {
                        report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC,
                                     "segment name `%s' not recognised",
                                     value);
                    } else {
                        in_abs_seg = FALSE;
                        location.segment = seg;
                    }
                    break;
                case 2:        /* [EXTERN label:special] */
                    if (*value == '$')
                        value++;        /* skip initial $ if present */
                    if (pass0 == 2) {
                        q = value;
                        while (*q && *q != ':')
                            q++;
                        if (*q == ':') {
                            *q++ = '\0';
                            ofmt->symdef(value, 0L, 0L, 3, q);
                        }
                    } else if (pass == 1) {     /* pass == 1 */
                        q = value;
                        validid = TRUE;
                        if (!isidstart(*q))
                            validid = FALSE;
                        while (*q && *q != ':') {
                            if (!isidchar(*q))
                                validid = FALSE;
                            q++;
                        }
                        if (!validid) {
                            report_error(ERR_NONFATAL,
                                         "identifier expected after EXTERN");
                            break;
                        }
                        if (*q == ':') {
                            *q++ = '\0';
                            special = q;
                        } else
                            special = NULL;
                        if (!is_extern(value)) {        /* allow re-EXTERN to be ignored */
                            int temp = pass0;
                            pass0 = 1;  /* fake pass 1 in labels.c */
                            declare_as_global(value, special,
                                              report_error);
                            define_label(value, seg_alloc(), 0L, NULL,
                                         FALSE, TRUE, ofmt, report_error);
                            pass0 = temp;
                        }
                    }           /* else  pass0 == 1 */
                    break;
                case 3:        /* [BITS bits] */
                    sb = get_bits(value);
                    break;
                case 4:        /* [GLOBAL symbol:special] */
                    if (*value == '$')
                        value++;        /* skip initial $ if present */
                    if (pass0 == 2) {   /* pass 2 */
                        q = value;
                        while (*q && *q != ':')
                            q++;
                        if (*q == ':') {
                            *q++ = '\0';
                            ofmt->symdef(value, 0L, 0L, 3, q);
                        }
                    } else if (pass2 == 1) {    /* pass == 1 */
                        q = value;
                        validid = TRUE;
                        if (!isidstart(*q))
                            validid = FALSE;
                        while (*q && *q != ':') {
                            if (!isidchar(*q))
                                validid = FALSE;
                            q++;
                        }
                        if (!validid) {
                            report_error(ERR_NONFATAL,
                                         "identifier expected after GLOBAL");
                            break;
                        }
                        if (*q == ':') {
                            *q++ = '\0';
                            special = q;
                        } else
                            special = NULL;
                        declare_as_global(value, special, report_error);
                    }           /* pass == 1 */
                    break;
                case 5:        /* [COMMON symbol size:special] */
                    if (*value == '$')
                        value++;        /* skip initial $ if present */
                    if (pass0 == 1) {
                        p = value;
                        validid = TRUE;
                        if (!isidstart(*p))
                            validid = FALSE;
                        while (*p && !isspace(*p)) {
                            if (!isidchar(*p))
                                validid = FALSE;
                            p++;
                        }
                        if (!validid) {
                            report_error(ERR_NONFATAL,
                                         "identifier expected after COMMON");
                            break;
                        }
                        if (*p) {
                            long size;

                            while (*p && isspace(*p))
                                *p++ = '\0';
                            q = p;
                            while (*q && *q != ':')
                                q++;
                            if (*q == ':') {
                                *q++ = '\0';
                                special = q;
                            } else
                                special = NULL;
                            size = readnum(p, &rn_error);
                            if (rn_error)
                                report_error(ERR_NONFATAL,
                                             "invalid size specified"
                                             " in COMMON declaration");
                            else
                                define_common(value, seg_alloc(), size,
                                              special, ofmt, report_error);
                        } else
                            report_error(ERR_NONFATAL,
                                         "no size specified in"
                                         " COMMON declaration");
                    } else if (pass0 == 2) {    /* pass == 2 */
                        q = value;
                        while (*q && *q != ':') {
                            if (isspace(*q))
                                *q = '\0';
                            q++;
                        }
                        if (*q == ':') {
                            *q++ = '\0';
                            ofmt->symdef(value, 0L, 0L, 3, q);
                        }
                    }
                    break;
                case 6:        /* [ABSOLUTE address] */
                    stdscan_reset();
                    stdscan_bufptr = value;
                    tokval.t_type = TOKEN_INVALID;
                    e = evaluate(stdscan, NULL, &tokval, NULL, pass2,
                                 report_error, NULL);
                    if (e) {
                        if (!is_reloc(e))
                            report_error(pass0 ==
                                         1 ? ERR_NONFATAL : ERR_PANIC,
                                         "cannot use non-relocatable expression as "
                                         "ABSOLUTE address");
                        else {
                            abs_seg = reloc_seg(e);
                            abs_offset = reloc_value(e);
                        }
                    } else if (pass == 1)
                        abs_offset = 0x100;     /* don't go near zero in case of / */
                    else
                        report_error(ERR_PANIC, "invalid ABSOLUTE address "
                                     "in pass two");
                    in_abs_seg = TRUE;
                    location.segment = NO_SEG;
                    break;
                case 7:        /* DEBUG       */
                    p = value;
                    q = debugid;
                    validid = TRUE;
                    if (!isidstart(*p))
                        validid = FALSE;
                    while (*p && !isspace(*p)) {
                        if (!isidchar(*p))
                            validid = FALSE;
                        *q++ = *p++;
                    }
                    *q++ = 0;
                    if (!validid) {
                        report_error(pass == 1 ? ERR_NONFATAL : ERR_PANIC,
                                     "identifier expected after DEBUG");
                        break;
                    }
                    while (*p && isspace(*p))
                        p++;
                    if (pass == pass_max)
                        ofmt->current_dfmt->debug_directive(debugid, p);
                    break;
                case 8:        /* [WARNING {+|-}warn-name] */
                    if (pass1 == 1) {
                        while (*value && isspace(*value))
                            value++;

                        if (*value == '+' || *value == '-') {
                            validid = (*value == '-') ? TRUE : FALSE;
                            value++;
                        } else
                            validid = FALSE;

                        for (i = 1; i <= ERR_WARN_MAX; i++)

⌨️ 快捷键说明

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