问题标签 [stack-machine]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1705 浏览

optimization - 如何优化简单的堆栈机器代码?

我一直在使用一种简单的基于堆栈的语言,而我发现自己反复做的一件事是手动优化代码块。

我想“嘿,这看起来很像计算机可以做的事情!具有明确目标和语义的重复工作。”。但是环顾四周,我找不到很多关于优化堆栈机器代码的东西。注册机器,是的。但不是基于堆栈的语言。这似乎是对“如何优化堆栈机器代码?”的普遍回应。是“不要”。

那么:如何优化堆栈机器代码?除了简单的窥视孔优化之外,还有什么通用的方法吗?是否有任何自动生成窥视孔优化的方法?

0 投票
1 回答
1473 浏览

variables - 为堆栈机器编译局部变量

我正在构建一个从类似 C 的语言到堆栈机器的玩具编译器,我现在需要弄清楚如何处理函数并阻止局部变量。抽象地思考一下,看起来我在频谱的两端有两个选择:1)为每个变量预处理和预分配堆栈空间,2)向 VM 添加特殊指令以遍历堆栈。

为每个变量预处理和预分配堆栈空间

这样做的好处是可以提前为我提供变量的所有地址,因此我不必非常聪明或向 VM 添加任何额外的指令来遍历堆栈。缺点是它可能非常浪费,因为从不执行但声明一大堆变量的条件代码将占用大量不必要的空间。例如,

在上面的代码中,即使test总是错误的,我仍然会为条件分支中的所有这些变量分配空间。

向 VM 添加特殊指令以遍历堆栈

我能想到的另一种方法是为每个变量声明生成代码,然后添加一些特殊的 VM 指令以在运行时找出这些变量的地址。这解决了浪费堆栈空间的问题,但增加了计算开销,我可以通过一些缓存方法来解决。

那么正确的方法是什么,还有另一种我认为更好的方法吗?

0 投票
0 回答
98 浏览

stack - MIPS 堆栈机器码

有一个像 MIPS 这样的代码块,我想将此代码转换为堆栈机器码。我一直在犹豫它的正确性。我不确定如何将值从“a”移动到“r1”。这是真的吗?谢谢你。

  • lw r1,a
  • lw r2,b
  • 添加 r3,r1,r2
  • sw r3,c

    堆栈机器码

    • 左值 r3
    • 推一个
    • 推b
    • +
    • :=
0 投票
2 回答
177 浏览

cpu-registers - 处理器是否使用多个堆栈将调用堆栈与表达式/寄存器堆栈分开?

我正在阅读一些关于处理器内存操作的基本文章,我对处理器如何处理接下来的内容感到困惑。

调用堆栈的概念很清楚,但我想知道表达式堆栈/寄存器堆栈(用于进行计算)是否是同一个堆栈,或者即使是子程序(函数)的局部变量的堆栈程序是同一个调用栈。

如果有人可以向我解释处理器如何处理其堆栈,那将对我有很大帮助。

0 投票
1 回答
1525 浏览

compiler-construction - 如何存储符号表编译器中的变量

对于我的课程,我必须为一小部分 Python 编写编译器:

  • 这种语言有一种方法
  • 没有函数,所以我只处理一个词法范围

这个 Python 子集将被翻译成 Java 字节码。我已经完成了词法分析和解析树(使用 lex 和 yacc)。我被困在代码生成上。

我们正在使用Gnoloo堆栈机器语言进行代码生成。

问题是我不知道如何存储变量。我知道我必须使用符号表,但我不知道如何填充它。

我必须存储变量的值吗?

如果代码有x = 2,符号表是否必须有一个字段?

如何存储堆栈机器的变量。

0 投票
0 回答
276 浏览

assembly - 组装堆栈机:Push/Pop 练习

假设地址 100 保存值 7,地址 200 保存值 3,使用冯诺依曼机定义解释算术指令 sub 的指令周期。

我知道答案是

  • push[100]所以栈顶是 7 ,因为地址 100 中的值是 7
  • push[200]所以栈顶是 3,因为地址 200 中的值是 3。
  • sub所以你减去 7 减去 3 即做 (7-3) 并且 4 将存储在堆栈地址 500 中。
  • pop[500]所以你弹出地址 500 中包含的值。所以 4 将被弹出并返回。”

我想问为什么 4 会存储在地址 500 中?

0 投票
1 回答
182 浏览

compiler-construction - 以基于堆栈机器的语言添加嵌套函数支持

假设我有一个简单的类 C 编程语言:

如您所见,它支持嵌套函数。
我已经实现了词法分析阶段,现在我正在研究代码生成和堆栈机器。大多数操作和简单的流程控制已经实现,但我需要一些帮助/想法如何解决嵌套函数任务。

堆栈机有两个寄存器,累加器和一个临时寄存器。
每个帧都包含:[arguments, local variables, return address, caller frame and stack pointer, temporaries and data operations],并且我对调用帧和操作评估使用相同的堆栈。也许我应该把它分成两个堆栈,一个用于调用帧,第二个用于操作评估。

我读到了两种实现嵌套函数的方法。一,使用激活链接(也称为静态链接),并显示。有没有更好的办法来处理这个问题?
如果我选择其中一个想法,是编译时间计算还是我需要在运行时存储一些东西?如果它是运行时的东西,它的时间复杂度是多少?是 O(1) 操作,还是类似于 O(k) 的操作,其中 k 是函数的深度。

0 投票
2 回答
1079 浏览

compiler-construction - 将 SSA 转换为堆栈机

众所周知,如何将代码从 SSA 表示转换为寄存器机器。(基本上,图形着色寄存器分配是这种转换的核心。)

但是从 SSA 转换为堆栈机的一般方法是什么?(CIL 字节码,在我正在查看的情况下。)我希望它更简单,因为不需要寄存器分配?

0 投票
1 回答
60 浏览

compiler-construction - 我的指令如何知道操作数堆栈上的地址指向什么?

我正在编写一个字节码编译器和一个虚拟机。我可以通过将任何非整数值放入常量池并将 4 字节整数地址推入堆栈来使用常量。那部分很好。

但现在我添加了全局变量,这些变量存储在我称之为“Ram”的虚拟内存区域中。当然,我存储在那里的值也会像常量一样按地址索引。因此,假设我将两个地址压入操作数堆栈,然后运行我的 FADD(浮动加法) - 当指令将两个地址从堆栈中弹出以执行加法时,它如何知道这些地址是否来自全局内存而不是到常量池?标准方法是什么?

0 投票
1 回答
199 浏览

assembly - 如何在汇编编程中将方法的结果传递回堆栈?

这是汇编代码:

我想更改这段代码,将方法 sumsquare 的结果传递回堆栈。如果我是对的,我所要做的就是不要将其存储在 RR 中,而是将其立即存储在变量 a 和 b 所在的堆栈中。所以我必须使用其他东西而不是 str RR。

指令系统

这些都是这个简单的堆栈机器上所有可能的指令