基于寄存器的VM与基于堆栈的VM之间的主要区别是什么?

时间:2012-10-12 11:42:49

标签: java android jvm dalvik

今天我正在阅读some slides about Andoird basics并且出现了这句话:

  

Dalvik VM基于寄存器而非基于堆栈。

那么,基于寄存器的VM与基于堆栈的VM之间的主要区别是什么?


第二个链接回答了我的问题:

http://markfaction.wordpress.com/2012/07/15/stack-based-vs-register-based-virtual-machine-architecture-and-the-dalvik-vm/

另一个链接:

http://androidjayavelu.blogspot.co.at/2011/06/dalvik-virtual-machine-vs-java-virtual.html

1 个答案:

答案 0 :(得分:2)

这篇文章也非常有用: http://www.codeproject.com/Articles/461052/Stack-based-vs-Register-based-Virtual-Machine-Arch

“基于堆栈的虚拟机 基于堆栈的虚拟机在上面的点中实现虚拟机所需描述的一般特征,但存储操作数的存储器结构是堆栈数据结构。通过从堆栈弹出数据,处理它们并以LIFO(后进先出)方式推回结果来执行操作。在基于堆栈的虚拟机中,添加两个数字的操作通常按以下方式执行(其中20,7和'结果'是操作数):

stackAdd

POP 20 POP 7 ADD 20,7,结果 推结果 由于PUSH和POP操作,需要四行指令来执行加法操作。基于堆栈的模型的优点在于操作数由堆栈指针(上图中的SP)隐式地寻址。这意味着虚拟机不需要显式地知道操作数地址,因为调用堆栈指针将给(Pop)下一个操作数。在基于堆栈的VM中,所有算术和逻辑运算都是通过推送和弹出操作数并在堆栈中生成来执行的。

基于注册的虚拟机 在基于寄存器的虚拟机实现中,存储操作数的数据结构基于CPU的寄存器。这里没有PUSH或POP操作,但是指令需要包含操作数的地址(寄存器)。也就是说,指令的操作数在指令中明确地被寻址,不像基于堆栈的模型,其中我们有一个指向操作数的堆栈指针。例如,如果要在基于寄存器的虚拟机中执行添加操作,则该指令或多或少如下:

registerAdd

ADD R1,R2,R3; #添加R1和R2的内容,将结果存储在R3中 正如我前面提到的,没有POP或PUSH操作,因此添加指令只是一行。但是与堆栈不同,我们需要明确地将操作数的地址称为R1,R2和R3。这里的优点是从堆栈推送和弹出的开销不存在,基于寄存器的VM中的指令在指令调度循环中执行得更快。

基于寄存器的模型的另一个优点是它允许在基于堆栈的方法中无法完成的某些优化。一个这样的例子是当代码中有共同的子表达式时,寄存器模型可以计算一次并将结果存储在寄存器中,以便在子表达式再次出现时将来使用,这样可以降低重新计算表达式的成本。

基于寄存器的模型的问题是平均寄存器指令大于平均堆栈指令,因为我们需要明确指定操作数地址。由于堆栈指针导致堆栈机器的指令很短,相应的寄存器机器指令需要包含操作数位置,并且与堆栈代码相比会产生更大的寄存器代码。

我遇到的一篇很棒的博客文章(在此链接中),包含基于寄存器的虚拟机的解释性和简单的C实现。如果实现虚拟机和解释器是您的主要兴趣,那么ANTLR创建者Terrence Parr的书名为“语言实现模式:创建您自己的特定领域和通用编程语言”,可能非常方便。“