int main(int argc, char **argv) ...{ pass0 = 1; want_usage = terminate_after_phase = FALSE; report_error = report_error_gnu; /**//* 设置报错函数句柄(感觉很有模块化的思想) */
nasm_set_malloc_error(report_error); /**//* nasmlib.c,对nasm_malloc_error赋值 */ offsets = raa_init(); /**//* 初始化struct RAA(建立树叶节点(貌似)) */ forwrefs = saa_init((long)sizeof(struct forwrefinfo)); /**//* 建立链表头,貌似 */
preproc = &nasmpp; /**//* 建立预处理函数,prepro.c(感觉很有模块化的思想) */ operating_mode = op_normal; /**//* 默认是预处理和汇编 */
error_file = stderr; /**//* 错误输出文件 */
seg_init();
register_output_formats(); /**//* outform.c,判断nasm是否有支持输出文件格式,如果没有,出错,如果有的话,返回默认的输出格式,默认是of_bin格式 */
parse_cmdline(argc, argv); /**//* 参数分析 */ if (terminate_after_phase) ...{ /**//* 判断在上面的处理过程中是否有发现错误,如果有,则退出 */ if (want_usage) usage(); return 1; }
/**//* If debugging info is disabled, suppress any debug calls */ if (!using_debug_info) ofmt->current_dfmt = &null_debug_form; /**//* 暂不解释*/
if (ofmt->stdmac) pp_extra_stdmac(ofmt->stdmac); /**//* 在preproc.c,将stdmac赋值给prepro.c里面的值进行处理,可能是为了更好的模块化吧? */ parser_global_info(ofmt, &location); /**//* parser.c,ofmt在之前设置默认值,默认值在register_output_formats()给出 */ eval_global_info(ofmt, lookup_label, &location); /**//* 在eval.c中,ofmt同上,lookup_label在labels.c中 */ /**//* location:Pointer to current line's segment,offset,由于模块化的原因,parser.c与eval.c中均有静态指针指向nasm.c中的loaction*/
/**//* define some macros dependent of command-line */ ...{ char temp[64]; snprintf(temp, sizeof(temp), "__OUTPUT_FORMAT__=%s ", ofmt->shortname); /**//* nasm将要处理的可执行文件格式 */ pp_pre_define(temp); /**//* preproc.c,功能??? */ }
/**//* 一下这一部分将结合接下来的分析进行,暂时不处理 */ switch (operating_mode) ...{ case op_depend: /**//* 生成依赖关系 */ ...{ char *line; preproc->reset(inname, 0, report_error, evaluate, &nasmlist); if (outname[0] == '') ofmt->filename(inname, outname, report_error); ofile = NULL; fprintf(stdout, "%s: %s", outname, inname); while ((line = preproc->getline())) nasm_free(line); preproc->cleanup(0); putc(' ', stdout); } break;
case op_preprocess: /**//* 仅仅进行预处理 */ ...{ char *line; char *file_name = NULL; long prior_linnum = 0; int lineinc = 0;
if (*outname) ...{ ofile = fopen(outname, "w"); if (!ofile) report_error(ERR_FATAL | ERR_NOFILE, "unable to open output file `%s'", outname); } else ofile = NULL;
location.known = FALSE;
/**//* pass = 1; */ preproc->reset(inname, 2, report_error, evaluate, &nasmlist); while ((line = preproc->getline())) ...{ /**//* * We generate %line directives if needed for later programs */ long linnum = prior_linnum += lineinc; int altline = src_get(&linnum, &file_name); if (altline) ...{ if (altline == 1 && lineinc == 1) nasm_fputs("", ofile); else ...{ lineinc = (altline != -1 || lineinc != 1); fprintf(ofile ? ofile : stdout, "%%line %ld+%d %s ", linnum, lineinc, file_name); } prior_linnum = linnum; } nasm_fputs(line, ofile); nasm_free(line); } nasm_free(file_name); preproc->cleanup(0); if (ofile) fclose(ofile); if (ofile && terminate_after_phase) remove(outname); } break;
case op_normal: /**//* 预处理与编译 */ ...{ /**//* * We must call ofmt->filename _anyway_, even if the user * has specified their own output file, because some * formats (eg OBJ and COFF) use ofmt->filename to find out * the name of the input file and then put that inside the * file. */ ofmt->filename(inname, outname, report_error);
ofile = fopen(outname, "wb"); if (!ofile) ...{ report_error(ERR_FATAL | ERR_NOFILE, "unable to open output file `%s'", outname); }
/**//* * We must call init_labels() before ofmt->init() since * some object formats will want to define labels in their * init routines. (eg OS/2 defines the FLAT group) */ init_labels();
ofmt->init(ofile, report_error, define_label, evaluate);
assemble_file(inname);
if (!terminate_after_phase) ...{ ofmt->cleanup(using_debug_info); cleanup_labels(); } else ...{ /**//* * We had an fclose on the output file here, but we * actually do that in all the object file drivers as well, * so we're leaving out the one here. * fclose (ofile); */ remove(outname); if (listname[0]) remove(listname); } } break; }
if (want_usage) usage();
raa_free(offsets); /**//* 删除 raa 数据结构 */ saa_free(forwrefs); /**//* 删除 saa 数据结构 */ eval_cleanup(); /**//* eval.c,释放编译过程产生的资源 */ nasmlib_cleanup(); /**//* nasmlib.c,释放编译过程产生的资源 */
if (terminate_after_phase) return 1; else return 0; }
|