首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译器设计防止寄存器覆盖

编译器设计防止寄存器覆盖
EN

Software Engineering用户
提问于 2016-01-31 15:07:07
回答 1查看 174关注 0票数 1

我正试图为一个带有指令集的自行设计的CPU编写一个编译器。CPU具有3个寄存器、2个输入寄存器(B和C)和一个输出寄存器(D)。例如,当执行ADD指令时,计算B和C的和并将其存储在D中。

我试图用访问者设计模式编写编译器:我有一堆语言树类,如"IfStatement“、”加法“、"Integer”和一个访问者“编译器”。访问者将查看树的每个节点,并将字节码附加到字节码列表的末尾。我不知道如何干净地处理寄存器重写:当计算表达式时

代码语言:javascript
复制
2*(7+3)

生成的字节码是

代码语言:javascript
复制
PUTb 2
PUTb 7
PUTc 3
ADD
MOVE D C
MUL

如您所见,2被7覆盖。

代码语言:javascript
复制
(7+3)*2

或者它可以存储临时结果是RAM,使用其他一些指令,这对于更复杂的表达式来说当然是必要的,比如

代码语言:javascript
复制
(7-5)*(8+3)

是否有一种干净的/面向对象的方法来处理这个问题?这里的访客模式不合适吗?我需要看一些先进的技术,如注册着色吗?编译器将用Java编写,但我认为这并不重要。

EN

回答 1

Software Engineering用户

回答已采纳

发布于 2016-01-31 15:59:48

您将需要一个溢出区域,可能是堆栈,或者是一些内存块。

您还需要在优化之前纠正生成的代码,因为优化损坏的代码基本上是不可能的。

因此,给定一个堆栈,您应该有类似于:PUT b,2; Push b; Put b,7; Put c,3; ADD; Pop b; MUL和如果使用内存的话,PUT b,2; Store b @1; Put b,7; Put c,3; ADD; Load b @1; MUL。接下来,为了获得优化,您可以通过根据简单的权重更改操作数的顺序,获得平衡树的单独传递。

编辑:

您可以创建一个数据结构来跟踪寄存器的内容(您可以假设语句开始时为空)。每次生成指令时,都会更新该数据结构以标记其中的内容(例如,哪个树节点和/或什么操作数、i.e.variable或常量或溢出临时变量)。

在生成操作之前,要确保其源在需要的寄存器中,如果没有,则从溢出区域、变量区域、常量区域/直接区或另一个寄存器执行负载。

(在设计上,您不应该需要在此时生成除某种负载之外的其他任何东西,例如,如果要生成MUL,就不必生成一个ADD,因为应该已经在适当的访问遍历中处理了这一点。)

但是--在执行任何操作数负载(这将覆盖寄存器)之前,如果有任何跟踪,您将生成一个存储到溢出区域。对目标/输出寄存器(例如MUL)也做同样的操作。并在整个过程中更新跟踪结构,以便生成的下一条指令将具有寄存器的状态&溢出温度,截止到代码中的当前点。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/308904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档