问题标签 [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.
jvm - 学习资源——堆栈机器,尤其是JVM
我很好奇是否有人有任何非常好的教程/文章/书籍来学习一般的堆栈机器,特别是 JVM。我知道这些:
http://www.artima.com/insidejvm/applets/EternalMath.html
http://www.ibm.com/developerworks/ibm/library/it-haggar_bytecode/
http://www.theserverside.com/tt/articles/article.tss?l=GuideJavaBytecode
显然 Bill Winners 和 Programming for the JVM 的书籍 Inside the JVM 很不错,尽管它们已经很旧了。
这些都在我的“toread”清单上,适合下雨的秋季周末。
有人有其他建议吗?
cpu-architecture - 注册机与堆栈机有何不同?
注册机与堆栈机有何不同?
jvm - 如何设计基于堆栈的机器的指令集?
基于堆栈的虚拟机(如 CLR 和 JVM)具有不同的指令集。在创建虚拟机时设计指令集背后有什么理论吗?例如,有 JVM 指令集将常量从 0-5 加载到堆栈上
而在 CLR 中有指令集将数字从 0 加载到 8 到堆栈中,如下所示
为什么没有ldc.i4.9
,如果ldc.i4 <int32 (num)>
有,为什么我们需要上述操作码?还有其他类似的。
我很想知道不同VM的操作码之间存在这种差异的原因是什么?是否有任何特定的理论来设计这些操作码,或者它完全由 VM 本身的特性驱动,还是取决于高级语言结构?
compiler-construction - 使用手写编译器生成字节码时如何处理作用域
我为一个简单的堆栈机器编写了一个小型编译器。它只能通过一些虚拟机黑客来组装和处理范围/功能。那就是我让它在字节码本身中定义范围和范围变量定义。
我能得到一些关于我应该如何处理范围的指示吗?
我面临的问题主要是,我如何让它知道何时以及何时不使用内部变量覆盖外部变量等。字节码是可变的,我更愿意改变它。
其他问题包括返回后如何将变量保留在外面。这样一个变量仍然有它的值。我可以将它推入堆栈,但我可以有很多变量。
我认为已经完成了一些编译器工作来检查这些事情,但我想不出需要做什么才能做到这一点。
compiler-construction - 如何在堆栈机器中找到 gc 根?
我正在为相当标准的堆栈机器编写编译器。现在我想添加一个垃圾收集器。我可以看到我可以生成某种“堆栈映射”来了解每个激活记录中哪些变量是 gc 根。但是,我不知道如何处理在执行期间压入堆栈的中间值。我正在编译的语言类似于 Pascal,所以我不需要也不想使用标签来识别来自其他数据类型的指针。
我将不胜感激有关如何
- 在任意时间点查找堆栈中的gc根(即如何识别已压入堆栈的中间值中哪些是gc根)。
- 编码此信息的常用形式(即,如何生成和编码“堆栈图”)
非常感谢!尼古拉斯
c++ - 堆栈机器在 C++ 代码中的使用有多普遍?
我正在查看一些 C++ 代码,它包含一个用于编写脚本的堆栈机器。我几年前学习了 C++,但从未在我的日常工作中使用它,所以我不知道这是常见的做法,还是仅在某些非常特定的情况下使用?
architecture - 栈和堆分离的虚拟机设计
我正在尝试通过实现书籍中的一些内容来更多地了解虚拟机和编程语言。我目前正在阅读的这本书将堆栈和堆保存在一个内存区域中。栈向上增长,堆向下增长。我想知道除了加载/存储操作的更简单策略之外,这样做的好处是什么,因为您不需要区分两个不同的内存区域。
我问的原因是因为我正在考虑偏离书中的计划,并为堆栈和堆设置两个不同的内存区域。这对我来说似乎更有意义,我不必担心堆栈和堆寄存器会相互冲突。
compiler-construction - 解释器、部分评估器和编译器的理论
所以我一直在学习堆栈机器、解释器、编译器和其他一些与编程语言及其一般理论相关的东西。我在书本和网上找到的大部分内容都非常专业,只讨论一个特定主题,例如口译员,而没有提及它与其他主题的关系,例如部分评估员。有没有很好的初学者资源来探索解释器、编译器和部分评估器之间的互连?好的资源我的意思是解释理论和具体实现的东西。我对这些东西了解得越多,我在日常工作中看到的地方就越多,如何应用所有这些东西,但缺乏对初学者友好的资源有点令人沮丧。
c - 为简单的 VM 编译 switch 语句
因此,出于学习目的,我将 C 的一个子集编译为一个简单的堆栈 VM,我想知道如何最好地编译 switch 语句,例如
我正在阅读的这本书提供了一种使用索引跳转编译它的简单方法,但书中描述的简单方案仅适用于连续的、升序的 case 值范围。
现在,我在第一遍使用符号标签,在第二遍中,我将把标签解析为实际的跳转目标,因为有了标签可以大大简化对堆栈指令的初始编译。我现在的想法是使用以下方案将书中的内容以任何顺序概括为任何 case 值序列。调用 case 值c1, c2, ..., cn
和相应的标签,然后假设 的值位于堆栈顶部,j1, j2, ..., jn
则生成以下指令序列:e
符号希望很清楚,但如果不是:dup
= 堆栈顶部的重复值,loadc c
= 将一个常量压入c
堆栈顶部,eq
= 比较堆栈上的顶部两个值并根据比较压入 0 或 1,jumpnz j
= 跳转到标签j
如果顶部堆栈值不为 0,则label:
= 在第二次编译过程中将解析为实际地址的东西。
所以我的问题是,编译 switch 语句的其他方法是什么?我的做法比连续范围的 case 值的索引跳转表要紧凑得多,但是当有很大的差距时效果很好。