寄存器机和栈机的区别

原文地址: What is difference between register machines & stack machines?

收获: 根据这篇文章了解了栈和寄存器的区别。

 

Unsurprisingly, the difference is that one is based on registers and the other is based on a stack. Note that the registers or stack are used for computations.

A register-based machine has a number of registers used for calculations. 2 + 3 would work something like this:

LOADI R4,#2 ;Load immediate 2 into register 4
LOADI R5,#3 ;Load immediate 3 into rester 5
ADD R4,R5 ; Add R4 and R5, storing result in R4

A stack computation would work like this

PUSHI #2 ;Push immediate 2 onto stack
PUSHI #3 ;Push immediate 3 onto stack
ADD ;Pop top two numbers, add them, and push results to the top of the stack.

Stack-based virtual machines are popular because they are terribly easy to write and compile for, and for a virtual machine they're pretty fast.

Register-based virtual machines are more like actual hardware. That has some advantages and disadvantages. All the stuff about which registers one is using, in a real machine, is handled by wires, so it doesn't take extra time. On a virtual register machine, the register numbers have to be decoded, taking steps. The advantage to a register-based architecture is that you can optimize compiled code much batter. If you have a value that needs to be kept for a while, you can store it in an unused register and just use it as needed. This works great on actual machines, but the extra overhead on virtual register machines sets the bar higher. I don't know the details of Dalvik, so I don't know how they address this.

Note that even register machines usually have a stack for passing return addresses and arguments to functions (though the first couple or three are usually passed in registers). Stack machines usually have a separate stack for return values. (It's possible to get around this, but it takes a lot of work and usually isn't worth it.)

Also, machine architectures didn't always have return stacks. On the CDC Cyber series, calling a function required replacing the first word with a jump to the return. When the function was done, it jumped to the first word of the function, which in turn jumped back. This is self-modifying code, which is pretty heinous under any circumstances, and falls apart with CPU caches. It also prevents reentrancy and recursion at a native level. It was fine for FORTRAN, though, which the Cybers were designed to do.

There are also some languages that do not work well with return stacks. It's very nice for C or C-like languages, so long as nothing goes wrong. When there are exceptions or setjmp/longjmp, whole chunks of the stack need to be thrown away. Scheme's call-with-current-continuation breaks it in such a way that it's a lot easier to use a heap-based machine with dynamically allocated states.

翻译如下: 

很简单,栈机是基于栈的,寄存器机是基于寄存器的,都是做计算的

寄存器机有一部分寄存器是用来做计算的。2+3的计算形式如下:
LOADI R4,#2 ;直接加载 2 到 寄存器 4
LOADI R5,#3 ;直接加载 3 到 寄存器 5
ADD R4,R5 ; Add R4 and R5, 结果存储在 in 寄存器4

栈机的计算形式如下:
PUSHI #2 ;直接推 2 进栈
PUSHI #3 ;直接推 3 进栈
ADD ;推出2和3相加, 把结果推到栈顶.

基于栈的虚拟机更受欢迎的原因是因为读取速度和编译非常快。

基于寄存器的虚拟机更像真实的硬件。它有一些优点和缺点,在一台真正的机器中,所有关于寄存器使用的东西都是通过电线处理的,因此不需要额外的时间。

  在虚拟寄存器机器上,必须对寄存器编号进行解码,并采取步骤.基于寄存器的体系结构的优点是可以优化编译后的代码。如果您有一个值需要保留一段时间,您可以将它存储在一个未使用的寄存器中,并根据需要使用它。这在实际的机器上工作得很好,但是虚拟寄存器机器中增加了更多的额外开销。我不知道Dalvik虚拟机的细节,所以我不知道他们是如何解决这个问题的。
注意,即使是寄存器机器也通常有一个栈,用于向函数传递返回地址和参数(尽管前两三个参数通常在寄存器中传递)。堆栈机器通常有一个单独的返回值堆栈。(有可能解决这个问题,但这需要大量的工作,通常不值得。)
  另外,机器架构并不总是有返回堆栈。在cdc-cyber系列中,调用一个函数需要用跳转返回来替换第一个单词。当函数完成时,它跳到函数的第一个字,然后又跳回来。这是一个自我修改的代码,在任何情况下都是非常糟糕的,并且会随着CPU缓存而崩溃。它还可以防止本机级别的可重入性和递归。不过,这对Fortran来说是不错的,而Cybers就是这样设计的。
还有一些语言不能很好地处理返回堆栈。它对于C或C类语言非常好,只要没有出错。当存在异常或setjmp/longjmp时,需要丢弃堆栈的整个块。Fortan语言使用当前继续符的调用中断了它,这样使用具有动态分配状态的基于堆的计算机就容易得多。

posted @ 2019-02-19 17:51  wpgraceii  阅读(803)  评论(0编辑  收藏  举报