[转载]LCC编译器的源程序分析(44)函数名称的代码生成

来源:互联网 发布:linux rar安装 编辑:程序博客网 时间:2024/06/04 19:02
当把所有的源程序生成DAG表示后,就进入了编译器的最后处理阶段,LCC是把DAG生成汇编的目标代码。在这一阶段,编译器为源程序定义和使用的变量选择存储单元,并把中间指令翻译成完成相同任务的汇编代码指令序列。在代码生成里,需要处理的问题是存储管理、指令选择、寄存器分配、计算次序等等。
在第一节里就已经看到了汇编代码生成,函数的名称生成如下:
#001 [global $main]
那么在LCC是怎么样生成上面的函数名称呢?现在就跟我来分析它的代码。
先从函数里funcdefn里调用代码:
#203  if (cfunc->sclass != STATIC)
#204         (*IR->export)(cfunc);
#205 
#206  if (glevel && IR->stabsym)
#207  {
#208         swtoseg(CODE); (*IR->stabsym)(cfunc);
#209  }
#210 
#211  swtoseg(CODE);
#212  
#213  (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls);
#214  
#215  if (glevel && IR->stabfend)
#216         (*IR->stabfend)(cfunc, lineno);
#217 
#218  foreach(stmtlabs, LABELS, checklab, NULL);
#219 
#220  exitscope();
#221 
#222  expect('}');
#223  labels = stmtlabs = NULL;
#224  retv = NULL;
#225  cfunc = NULL;
203行就是判断函数是否静态函数,如果不是静态函数,就会调用后端的接口来生成函数的名称。
204行的调用接口的代码如下:
#001 static void export(Symbol p)
#002 {
#003 
#004 #if 0
#005  print("public %s/n", p->x.name);
#006 #else
#007  print("[global %s]/n", p->x.name);
#008  #endif
#009 
#010 }
由于IR->export是一个函数指针,只要设置不同的函数指针,就可以生成不同的函数名称。这就是LCC可以生成不同机器代码的原因。
7行里是生成函数的名称main,它是调用print函数输出到文件里。p->x.name是符号表里的函数名称。很简单吧,就这样可以生成不同的函数名称了。  
原创粉丝点击