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

📄 nasm.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
        globallineno = 0;
        if (passn == 1)
            location.known = true;
        location.offset = offs = GET_CURR_OFFS;

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

            /* here we parse our directives; this is not handled by the 'real'
             * parser. */
            directive = line;
	    d = getkw(&directive, &value);
            if (d) {
		int err = 0;

                switch (d) {
                case D_SEGMENT:		/* [SEGMENT n] */
		case D_SECTION:
                    seg = ofmt->section(value, pass2, &sb);
                    if (seg == NO_SEG) {
                        report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC,
                                     "segment name `%s' not recognized",
                                     value);
                    } else {
                        in_abs_seg = false;
                        location.segment = seg;
                    }
                    break;
                case D_EXTERN:		/* [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 (passn == 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 D_BITS:		/* [BITS bits] */
                    globalbits = sb = get_bits(value);
                    break;
                case D_GLOBAL:		/* [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 D_COMMON:		/* [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 && !nasm_isspace(*p)) {
                            if (!isidchar(*p))
                                validid = false;
                            p++;
                        }
                        if (!validid) {
                            report_error(ERR_NONFATAL,
                                         "identifier expected after COMMON");
                            break;
                        }
                        if (*p) {
                            int64_t size;

                            while (*p && nasm_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 (nasm_isspace(*q))
                                *q = '\0';
                            q++;
                        }
                        if (*q == ':') {
                            *q++ = '\0';
                            ofmt->symdef(value, 0L, 0L, 3, q);
                        }
                    }
                    break;
                case D_ABSOLUTE:		/* [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 (passn == 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 D_DEBUG:		/* [DEBUG] */
                    p = value;
                    q = debugid;
                    validid = true;
                    if (!isidstart(*p))
                        validid = false;
                    while (*p && !nasm_isspace(*p)) {
                        if (!isidchar(*p))
                            validid = false;
                        *q++ = *p++;
                    }
                    *q++ = 0;
                    if (!validid) {
                        report_error(passn == 1 ? ERR_NONFATAL : ERR_PANIC,
                                     "identifier expected after DEBUG");
                        break;
                    }
                    while (*p && nasm_isspace(*p))
                        p++;
                    if (pass0 == 2)
                        ofmt->current_dfmt->debug_directive(debugid, p);
                    break;
                case D_WARNING:		/* [WARNING {+|-|*}warn-name] */
                    if (pass1 == 1) {
                        while (*value && nasm_isspace(*value))
                            value++;

                        switch(*value) {
                            case '-': validid = 1; value++; break;
                            case '+': validid = 1; value++; break;
                            case '*': validid = 2; value++; break;
                            default:  validid = 1; break;
                        }

                        for (i = 1; i <= ERR_WARN_MAX; i++)
                            if (!nasm_stricmp(value, warnings[i].name))
                                break;
                        if (i <= ERR_WARN_MAX) {
                            switch(validid) {
			    case 0:
				warning_on[i] = false;
				break;
			    case 1:
				warning_on[i] = true;
				break;
			    case 2:
				warning_on[i] = warning_on_global[i];
				break;
                            }
                        }
                        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 && nasm_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) {
                    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) {
                    if (passn == 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;
                            }
                        }
                    }
                }

                /*  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 {
                        /*
                         * 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)

⌨️ 快捷键说明

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