LCC编译器的源程序分析(46)计算需要使用栈大小

从目标代码里,可以看到下面一行:
#009 sub esp, 16
在这行里是保留栈的大小,值为16。但16个字节是怎么样计算出来的呢?下面就来分析LCC的代码,看它是怎么样计算的。它是在函数 gencode 里进行计算的,它的代码如下:
#001 void gencode(Symbol caller[], Symbol callee[])
#002 {
#003      Code cp;
#004      Coordinate save;
#005 
#006      if (prunetemps == -1)
#007           prunetemps = !IR->wants_dag;
#008      save = src;
#009      if (assignargs)
#010      {
#011           int i;
#012           Symbol p, q;
#013           cp = codehead.next->next;
#014           codelist = codehead.next;
#015           for (i = 0; (p = callee[i]) != NULL
#016                 && (q = caller[i]) != NULL; i++)
#017                 if (p->sclass != q->sclass || p->type != q->type)
#018                      walk(asgn(p, idtree(q)), 0, 0);
#019           codelist->next = cp;
#020           cp->prev = codelist;
#021      }
#022 
#023      if (glevel && IR->stabsym)
#024      {
#025           int i;
#026           Symbol p, q;
#027           for (i = 0; (p = callee[i]) != NULL
#028                 && (q = caller[i]) != NULL; i++)
#029           {
#030                 (*IR->stabsym)(p);
#031                 if (p->sclass != q->sclass || p->type != q->type)
#032                      (*IR->stabsym)(q);
#033           }
#034           swtoseg(CODE);
#035      }
#036 
#037      cp = codehead.next;
#038      for ( ; errcnt <= 0 && cp; cp = cp->next)
#039           switch (cp->kind)
#040      {
#041           case Address: assert(IR->address);
#042                 (*IR->address)(cp->u.addr.sym, cp->u.addr.base,
#043                      cp->u.addr.offset); break;
#044           case Blockbeg:
#045                 {
#046                       Symbol *p = cp->u.block.locals;
#047                      (*IR->blockbeg)(&cp->u.block.x);
#048                      for ( ; *p; p++)
#049                            if ((*p)->ref != 0.0)
#050                                  (*IR->local)(*p);
#051                            else if (glevel) (*IR->local)(*p);
#052                 }
#053                 break;
#054           case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break;
#055           case Defpoint: src = cp->u.point.src; break;
#056           case Gen: case Jump:
#057           case Label:   
#058                 if (prunetemps)
#059                      cp->u.forest = prune(cp->u.forest);
#060                 fixup(cp->u.forest);
#061                 cp->u.forest = (*IR->gen)(cp->u.forest); break;
#062           case Local:   
#063                 (*IR->local)(cp->u.var); break;
#064           case Switch:   break;
#065           default: assert(0);
#066      }
#067      src = save;
#068 }
#069 
计算栈大小的代码是从44行开始到第53行为止。第44行是处理块代码的开始类型。
第46行是获取当前代码块的符号表。
第47行是清空环境变量。
第48行到第51行是循环地计算所有变量的需要使用栈大小。后面再接分析怎么样计算变量占用栈的大小。
 

你可能感兴趣的:(null,编译器)