标签: stack-based

寄存器与堆栈

使用基于寄存器的虚拟机与使用基于堆栈的虚拟机有什么优缺点?

对我而言,基于寄存器的机器似乎更直接的编程和更高效.那么为什么JVM,CLR和Python VM都是基于堆栈的呢?

language-agnostic stack-based vm-implementation

56
推荐指数
5
解决办法
2万
查看次数

为什么微软的开发人员选择将.NET作为基于堆栈的机器?

今天我在VS2008提供的工具之间找到了Disassembler IL.我试图反汇编程序并查看结果.操作码不是很难理解,但有一件事让我感到惊讶:.NET是基于堆栈的吗?!阅读"写出优秀的代码,第二卷"我没有得到基于堆栈的机器的良好画面,因为它们非常慢.它们也很容易实现,但我不认为MS开发人员因为它的简单性而选择了这种方法,毕竟代码必须转换成真正的机器代码才能解决问题.
谁能解释这个奇怪的选择吗?

PS:
我在这里发布了关于这个主题的内容:

13.1.1基于 堆栈的机器基于堆栈的机器使用内存进行大多数计算,在内存中使用堆栈来保存所有操作数和结果.采用堆栈架构的计算机系统提供了一些优于其他架构的重要优势:

  • 这些指令通常比其他架构中的指令更小(每个消耗更少的字节),因为指令通常不必指定任何操作数.
  • 编写堆栈体系结构的编译器通常比编写其他机器更容易,因为将算术表达式转换为一系列堆栈操作非常容易.
  • 堆栈体系结构中很少需要临时变量,因为堆栈本身就是为此目的服务的.
不幸的是,堆栈计算机也存在一些严重的缺点:
  • 几乎每个指令都引用内存(现代机器上的内存很慢).虽然缓存有助于缓解此问题,但内存性能仍然是堆栈计算机上的主要问题.
  • 即使从HLL到堆栈计算机的转换非常容易,优化的机会也比其他架构少.
  • 由于堆栈计算机不断访问相同的数据元素(即堆栈顶部的数据),因此很难实现流水线操作和指令并行性(有关流水线操作和指令并行性的详细信息,请参阅写入优秀代码,第1卷).
堆栈是一种数据结构,它只允许在堆栈的一些有限元素上进行操作(通常称为堆栈顶部,堆栈旁边).使用堆栈,您通常可以执行以下三种操作之一:将新数据推送到堆栈,从堆栈弹出数据,或对当前位于堆栈顶部的数据(以及可能紧接在堆栈下方的数据)进行操作.

13.1.1.5真实堆栈机器
堆栈架构的一大优点是可以很容易地为这样的机器编写编译器.为基于堆栈的机器编写仿真器也非常容易.由于这些原因,堆栈体系结构在诸如Java虚拟机和Microsoft Visual Basic p代码解释器之类的虚拟机(VM)中很流行.确实存在一些基于堆栈的真实CPU,例如Java VM的硬件实现; 但是,由于内存访问的性能限制,它们并不是很受欢迎.尽管如此,了解堆栈体系结构的基础知识非常重要,因为许多编译器在转换为实际机器代码之前将HLL源代码转换为基于堆栈的形式.实际上,在最坏的情况下(尽管很少见),编译器在编译复杂的算术表达式时会被迫发出模拟基于堆栈的机器的代码.

编辑:我刚刚在@ EricLippert的博客中发现了一篇文章,回答了这个问题并确认了@Aaron的答案

.net stack-based

21
推荐指数
1
解决办法
1088
查看次数

我将如何实现一个简单的基于堆栈的编程语言

我有兴趣通过实现基于堆栈的编程语言来扩展我对计算机编程的了解.我正在寻找关于从哪里开始的建议,因为我打算让它具有像" pushint 1"这样的函数,它可以将值为1的整数推送到堆栈的顶部,并通过像" L01: jump L01:" 这样的标签来控制流量.

到目前为止,我已经实现了我希望我的语言行为的C#实现(想要链接到它但IDEOne被阻止),但它非常混乱,需要优化.它将输入转换为XML,然后解析它.我的目标是使用较低级别的语言(可能是C/C++),但我的问题是实现一个可以容纳各种数据类型并且没有固定大小的堆栈.

最后我还想实现数组和函数.另外,我认为我需要有一个更好的Lexer,我想知道解析树是否适合这种简单的语言.

任何建议/批评都是受欢迎的,请考虑我仍然是编程的新手(我刚刚完成了AP CompSci I).此外,欢迎链接到基于开源堆栈的语言.

这是一个基本的程序,我想尝试解释/编译(在哪里[this is a comment]):

[Hello World!]
pushchar    '\n'
pushstring  "Hello World!"
print
[Count to 5 and then count down!]
pushint     1
setlocal    0
L01:
pushchar    '\n'
getlocal    0
print           [print x + '\n']
getlocal    0
increment
setlocal    0   [x = x + 1]
pushint     5
getlocal    0
lessthan        [x < 5]
iftrue      L01
L02:
pushchar    '\n'
getlocal    0
print           [print x + '\n']
getlocal …
Run Code Online (Sandbox Code Playgroud)

parsing stack-based lexer

8
推荐指数
1
解决办法
4039
查看次数

基于寄存器+堆栈的虚拟机如何工作?

我知道如何基于寄存器以及基于堆栈的虚拟机如何独立工作.我知道两者的优点和缺点.我想知道的是,有没有人试图合并这两者?

我试图在网上搜索这种虚拟机的存在,但无济于事.我得到的最好结果是一篇关于混合虚拟机(HyVM)的文章.如果确实为编程语言创建了这样的虚拟机,我将有兴趣查看其源代码以了解它是如何工作的.

也许有人可以指出我找到这样一个虚拟机的正确方向,或者将我链接到本主题中详述的文章或博客文章.

register-allocation stack-based cpu-registers ssa vm-implementation

6
推荐指数
1
解决办法
586
查看次数

为什么基于寄存器的虚拟机比基于堆栈的虚拟机更好?

为什么基于寄存器的虚拟机比基于堆栈的虚拟机更好?

具体来说,在Parrot VM的文档中,设计师解释了注册机的好处:

[...]高级语言中的许多程序由嵌套的函数和方法调用组成,有时使用词法变量来保存中间结果.在非JIT设置下,基于堆栈的VM将弹出,然后多次推送相同的操作数,而基于寄存器的VM将简单地分配适当数量的寄存器并对其进行操作,这可以显着减少操作量和CPU时间.

但为什么同样的操作数被推多次?

language-agnostic stack-based vm-implementation

6
推荐指数
1
解决办法
1253
查看次数

类似于c ++中用于javascript的基于堆栈的对象

在javascript中寻找一个构造,就像在c ++中的stackbased或local对象中的析构函数一样,例如

#include <stdio.h>
class M {
public:
  int cnt;
  M()        {cnt=0;}
  void inc() {cnt++;}
  ~M()       {printf ("Count is %d\n", cnt);}
};
...
{M m;
 ...
 m.inc ();
 ...
 m.inc ();
} // here the destructor of m will printf "Count is 2");
Run Code Online (Sandbox Code Playgroud)

所以这意味着我正在寻找一个构造,当它的范围结束时(当它"超出范围"时)执行一个动作.它应该是健壮的,因为它不需要在范围结束时采取特殊操作,就像c ++中的析构函数那样(用于包装mutex-alloc和release).

干杯,毫克

javascript c++ destructor scope stack-based

5
推荐指数
1
解决办法
229
查看次数

Objective-C中基于堆栈的数组声明?

在Objective-C中,我声明了一个像这样的C数组:

int length = 10;
int a [length];

这不会导致Xcode中的任何错误,但会导致其他编译器,如Visual Studio.请告诉我它是如何工作的.我应该使用它还是使用malloc/calloc?

arrays objective-c stack-based

2
推荐指数
1
解决办法
180
查看次数

'腐'运算符的必要性

为什么Forth实现了rot运算符,为什么它在堆栈的三个最顶层项目上运行?

这只是为了方便还是在没有这样的指示的情况下Forth不是Turing-complete?三个数量是图灵完成的最小可行选择吗?

我可以想象一个人可以rotpick或实现roll.因此,如果这三个操作都没有,那么它仍然是图灵完成的吗?

forth stack-based computation computation-theory formal-languages

1
推荐指数
1
解决办法
230
查看次数