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

📄 nasm.c

📁 nasm早期的源代码,比较简单是学习汇编和编译原理的好例子
💻 C
📖 第 1 页 / 共 5 页
字号:
                    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++)
                            if (!nasm_stricmp(value, suppressed_names[i]))
                                break;
                        if (i <= ERR_WARN_MAX)
                            suppressed[i] = validid;
                        else
                            report_error(ERR_NONFATAL,
                                         "invalid warning id in WARNING directive");
                    }
                    break;
                case D_CPU:		/* [CPU] */
                    cpu = get_cpu(value);
                    break;
                case D_LIST:		/* [LIST {+|-}] */
                    while (*value && isspace(*value))
                        value++;

                    if (*value == '+') {
                        user_nolist = 0;
                    } else {
                        if (*value == '-') {
                            user_nolist = 1;
                        } else {
			    err = 1;
                        }
                    }
                    break;
		case D_DEFAULT:		/* [DEFAULT] */
		    stdscan_reset();
                    stdscan_bufptr = value;
                    tokval.t_type = TOKEN_INVALID;
		    if (stdscan(NULL, &tokval) == TOKEN_SPECIAL) {
			switch ((int)tokval.t_integer) {
			case S_REL:
			    globalrel = 1;
			    break;
			case S_ABS:
			    globalrel = 0;
			    break;
			default:
			    err = 1;
			    break;
			}
		    } else {
			err = 1;
		    }
		    break;
		case D_FLOAT:
		    if (float_option(value)) {
			report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC,
				     "unknown 'float' directive: %s",
				     value);
		    }
		    break;
                default:
                    if (!ofmt->directive(directive, value, pass2))
                        report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC,
                                     "unrecognised directive [%s]",
                                     directive);
                }
		if (err) {
		    report_error(ERR_NONFATAL,
				 "invalid parameter to [%s] directive",
				 directive);
		}
            } else {            /* it isn't a directive */

                parse_line(pass1, line, &output_ins,
                           report_error, evaluate, def_label);

                if (!(optimizing > 0) && pass == 2) {
                    if (forwref != NULL && globallineno == forwref->lineno) {
                        output_ins.forw_ref = true;
                        do {
                            output_ins.oprs[forwref->operand].opflags |=
                                OPFLAG_FORWARD;
                            forwref = saa_rstruct(forwrefs);
                        } while (forwref != NULL
                                 && forwref->lineno == globallineno);
                    } else
                        output_ins.forw_ref = false;
                }

                if (!(optimizing > 0) && output_ins.forw_ref) {
                    if (pass == 1) {
                        for (i = 0; i < output_ins.operands; i++) {
                            if (output_ins.oprs[i].
                                opflags & OPFLAG_FORWARD) {
                                struct forwrefinfo *fwinf =
                                    (struct forwrefinfo *)
                                    saa_wstruct(forwrefs);
                                fwinf->lineno = globallineno;
                                fwinf->operand = i;
                            }
                        }
                    } else {    /* pass == 2 */
                        /*
                         * Hack to prevent phase error in the code
                         *   rol ax,x
                         *   x equ 1
                         *
                         * If the second operand is a forward reference,
                         * the UNITY property of the number 1 in that
                         * operand is cancelled. Otherwise the above
                         * sequence will cause a phase error.
                         *
                         * This hack means that the above code will
                         * generate 286+ code.
                         *
                         * The forward reference will mean that the
                         * operand will not have the UNITY property on
                         * the first pass, so the pass behaviours will
                         * be consistent.
                         */

                        if (output_ins.operands >= 2 &&
                            (output_ins.oprs[1].opflags & OPFLAG_FORWARD) &&
			    !(IMMEDIATE & ~output_ins.oprs[1].type))
			{
			    /* Remove special properties bits */
			    output_ins.oprs[1].type &= ~REG_SMASK;
                        }

                    }           /* pass == 2 */

                }

                /*  forw_ref */
                if (output_ins.opcode == I_EQU) {
                    if (pass1 == 1) {
                        /*
                         * Special `..' EQUs get processed in pass two,
                         * except `..@' macro-processor EQUs which are done
                         * in the normal place.
                         */
                        if (!output_ins.label)
                            report_error(ERR_NONFATAL,
                                         "EQU not preceded by label");

                        else if (output_ins.label[0] != '.' ||
                                 output_ins.label[1] != '.' ||
                                 output_ins.label[2] == '@') {
                            if (output_ins.operands == 1 &&
                                (output_ins.oprs[0].type & IMMEDIATE) &&
                                output_ins.oprs[0].wrt == NO_SEG) {
                                int isext =
                                    output_ins.oprs[0].
                                    opflags & OPFLAG_EXTERN;
                                def_label(output_ins.label,
                                          output_ins.oprs[0].segment,
                                          output_ins.oprs[0].offset, NULL,
                                          false, isext, ofmt,
                                          report_error);
                            } else if (output_ins.operands == 2
                                       && (output_ins.oprs[0].
                                           type & IMMEDIATE)
                                       && (output_ins.oprs[0].type & COLON)
                                       && output_ins.oprs[0].segment ==
                                       NO_SEG
                                       && output_ins.oprs[0].wrt == NO_SEG
                                       && (output_ins.oprs[1].
                                           type & IMMEDIATE)
                                       && output_ins.oprs[1].segment ==
                                       NO_SEG
                                       && output_ins.oprs[1].wrt ==
                                       NO_SEG) {
                                def_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 {    /* pass == 2 */
                        /*
                         * Special `..' EQUs get processed here, except
                         * `..@' macro processor EQUs which are done above.
                         */
                        if (output_ins.label[0] == '.' &&
                            output_ins.label[1] == '.' &&
                            output_ins.label[2] != '@') {
                            if (output_ins.operands == 1 &&
                                (output_ins.oprs[0].type & IMMEDIATE)) {
                                define_label(output_ins.label,
                                             output_ins.oprs[0].segment,
                                             output_ins.oprs[0].offset,
                                             NULL, false, false, ofmt,
                                             report_error);
                            } else if (output_ins.operands == 2
                                       && (output_ins.oprs[0].
                                           type & IMMEDIATE)
                                       && (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");
                        }
                    }           /* pass == 2 */
                } else {        /* instruction isn't an EQU */

                    if (pass1 == 1) {

                        int32_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_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;
                            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 {    /* 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 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++;

⌨️ 快捷键说明

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