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行是循环地计算所有变量的需要使用栈大小。后面再接分析怎么样计算变量占用栈的大小。
 

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