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

计算栈的大小,是通过后端接口的代码来完成计算的。栈的大小,主要就是局部变量、临时变量、调用参数和返回值等使用的字节大小,如果变量可以放到寄存器,就不需加到栈的大小里。上面已经看了下面的代码:
#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;
 
现在,就接着查看IR->blockbeg接口的函数,它的代码如下:
#001 void blockbeg(Env *e) {
#002     e->offset = offset;
#003     e->freemask[IREG] = freemask[IREG];
#004     e->freemask[FREG] = freemask[FREG];
#005 }
第2行是保存当前使用栈的大小。
3 行是保存使用的寄存器。
4 行是保存自由的寄存器。
 
IR->local接口的代码如下:
#001 static void local(Symbol p) {
#002  if (isfloat(p->type))
#003         p->sclass = AUTO;
#004  if (askregvar(p, (*IR->x.rmap)(ttob(p->type))) == 0) {
#005         assert(p->sclass == AUTO);
#006         offset = roundup(offset + p->type->size,
#007               p->type->align < 4 ? 4 : p->type->align);
#008         p->x.offset = -offset;
#009         p->x.name = stringd(-offset);
#010  }
#011 }
这个函数 local 是计算一个符号使用栈的开始位置。
2 行判断是否是浮点数据类型,如果是就设置为自动存储类型。
4 行是查询这个符号是否可以使用寄存器,如果不使用寄存器,就放置在栈里,然后就添加栈的大小。
6 行是按 4 字节对齐取整栈的开始位置。
8 行和第 9 行是保存变量保存在栈的开始位置。

下一节再来分析寄存器分配部分的函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值