assembly 如何计算给定表达式的临时数?

tjjdgumg  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(99)

我正在努力理解我在一个在线编译器课程上做错了什么,而且没有多少在线资源可以帮助我找出我的错误。
问题是:
使用视频讲座中介绍的简单代码生成技术评估以下两个表达式:E1=e1+e2+e3+e4+e5 E2=e1+(e2+(e3+(e4+e5)))确定E1和E2评估中所需临时人员数量(NT)的正确结论。
选择所有适用项:

  • [ ] 对于e1、e2、e3、e4和e5中的任何选择,NT(E1)NT(E2)。
  • [ ] 对于e1、e2、e3、e4和e5中的任何选择,NT(E1)NT(E2)。
  • [ ] 对于e1、e2、e3、e4和e5中的任何选择,NT(E1)= NT(E2)。
  • [ ] 对于e1、e2、e3、e4和e5的不同选择, predicate NT(E1)NT(E2)、NT(E1)= NT(E2)和NT(E1)NT(E2)都可以为真。
  • [ ] 如果e1、e2、e3、e4和e5都是整数文字,则NT(E1)NT(E2)。
  • [ ] 如果e1、e2、e3、e4和e5都是整数文字,则NT(E1)= NT(E2)。
  • [ ] 如果e1、e2、e3、e4和e5都是整数文字,则NT(E1)NT(E2)。

看起来E1和E2需要相同数量的暂存器。关于这个主题,我已经答对了所有其他的问题,所以我真的很困惑。

svujldwt

svujldwt1#

如果简单的代码生成选择是在树的初始遍历过程中将左操作数物化到寄存器中,然后物化右操作数,然后执行算术运算,如加法,则第一个表达式将需要2个暂存器,因此对于E1=e1+e2+e3+e4+e5:

load t1, e1
load t2, e2
add t1,t1,t2 
load t2, e3
add t1, t1, t2
load t2, e4 
add t1, t1, t2
load t2, e5
add t1, t1, t2
store t1, E1

这里的要点是操作数的寄存器在执行加法后立即被释放,因此t1和t2都被释放。因此,尽管t1被回收用于结果,但t2可用于下一次物化。
而对于E2=e1+(e2+(e3+(e4+e5))),我们将得到:

load t1, e1
load t2, e2
load t3, e3
load t4, e4
load t5, e5
add t4, t4, t5
add t3, t3, t4
add t2, t2, t3
add t1, t1, t2
store t1, E2

如果代码生成是如上所述的那样幼稚,因为寄存器在加法运算完成之前不能被释放,但是树被遍历一次,所有必要的操作都直接执行。
堆栈机的代码生成过程类似,用push替换load,而add没有操作数,因此对于第一个表达式,push,push,add,push,add,push add,而对于第二个表达式,push,push,push,add,add。
显然,可以对代码生成进行改进,以便延迟将表达式具体化到寄存器中,如下所示:计算左操作数,但如果它是简单的(例如变量或立即数),则将其留在内存中,类似地计算右操作数,然后重新访问左操作数并将其加载到寄存器(如果尚未加载),然后类似地重新访问右操作数,最后执行加法,释放左操作数和右操作数的两个寄存器,同时还为结果声明寄存器。

相关问题