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

📄 nasm.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
               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++)
		        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 9:  /* cpu */
                  cpu = get_cpu (value);
                  break;
               case 10:        /* fbk 9/2/00 */       /* [LIST {+|-}] */
                   while (*value && isspace(*value))
                       value++;

                   if (*value == '+') {
                       user_nolist = 0;
		     }
                     else {
                          if (*value == '-') {
                          user_nolist = 1;
                          }
                          else {
                              report_error (ERR_NONFATAL, "invalid parameter to \"list\" directive");
                          }
                      }
                  break;
               default:
                  if (!ofmt->directive (directive, value, pass2))
                     report_error (pass1==1 ? ERR_NONFATAL : ERR_PANIC,
                              "unrecognised directive [%s]",
                              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))
                        {
                           output_ins.oprs[1].type &= ~(ONENESS|BYTENESS);
                        }

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

                        long 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 */
                           long 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;
                                    default:
                                       typeinfo = TY_LABEL;

                           }

                           ofmt->current_dfmt->debug_typevalue(typeinfo);

                        }

⌨️ 快捷键说明

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