【问题标题】:Assembly language - Stack machine汇编语言 - 堆栈机
【发布时间】:2012-04-05 19:06:53
【问题描述】:

我在业余时间学习汇编语言以成为更好的开发人员。

我在概念层面理解基于堆栈的机器和基于寄存器的机器之间的区别,但我想知道基于堆栈的机器实际上是如何实现的。如果是虚拟机,例如JVM 或 .NET,在基于寄存器的架构上运行,例如x86 或 x64,那么它必须在程序集级别使用寄存器(就我而言)。我显然在这里遗漏了一些东西。因此我不确定汇编语言的区别。

我在这里阅读过文章,例如Stack-based machine depends on a register-based machine? 和维基百科,但我不相信他们会直接回答我的问题。

【问题讨论】:

  • 他们可以在软件中模拟它,旧版 JVM 就是这样做的。通常,尽管堆栈机器代码被编译为本机代码(无论可能是什么架构)。堆栈机器代码很好,因为它具有简洁的编码,很容易从 AST 生成并且相对容易分析。

标签: assembly x86 masm


【解决方案1】:

基于堆栈的机器很少用硬件实现——我只听说过一种这样的实现,而且从来没有机会研究过。

实际上,堆栈机器是由本地解释器在基于真实寄存器的处理器上实现的。本质上,理论上的 Stack 机器是由真实的基于 Register 的机器模拟的。

所以回答你的问题:虽然堆栈机器的机器代码没有寄存器,但执行这些指令的本机解释器确实有寄存器并将使用它们。

问:那么为什么是间接的呢? A:可移植性——堆栈机器的指令集可以在任意数量的不同的基于寄存器的机器上进行仿真。这意味着相同的 JVM 应用程序可以在任何具有解释器的机器上运行,因此旧的 Java 口号“编写一次,随处运行”

【讨论】:

  • “本地解释器”是什么意思。您指的是 JIT 编译器(在 .NET 的情况下)?
  • “本地解释器”是指在本地机器上运行的应用程序,它读取堆栈机器指令并执行它们。每种类型的机器(和操作系统)都有不同的“本机解释器”。在 Java 的情况下,“本机解释器”是 JVM。 JIT 略有不同。
  • 仅供参考,JIT 是将堆栈机器指令转换为本地机器的等效指令集(基于寄存器的指令)的东西。这是为了让应用程序的性能接近原生处理器的性能,但同时保持可移植性的优势。
  • Hans Passant@ 确实,本机处理器不需要 使用寄存器,但实际上 1) 寄存器比堆栈快得多,因此为了提高性能,你' d 可能想要。 2) 在许多基于 CISC 的处理器上,并非所有指令都可以在堆栈数据上执行。数据必须先加载到寄存器中,然后才能对其进行操作。也就是说,由解释器开发人员决定如何执行指令。
  • 谢谢。你指的是解释器,这让我有点困惑,因为我知道 .NET 和 Java 是编译语言;不像 PHP,它是解释的。你能澄清一下吗?再次感谢。
【解决方案2】:

作为参考,Burroughs B5000Inmos Transputer 是堆栈机器。 DEC PDP11 具有如此灵活的寻址模式,可以用作堆栈机。我想Niklaus Wirth's Lilith 可能是一个堆栈机器(20 多年前,我的脑子在滑:-)

它们在查找操作数的指令中确实没有任何寄存器名称/编号,因为它们在堆栈上。

指令可以将立即(常量)值加载到堆栈,或加载/存储到内存。

所以他们不是add.w r0, r1, r5add.w eax, [#fe34]。有add.w

因此,一个汇编程序序列的示例(完全不准确,它更复杂)可能是

loadstack 0xfe34   -- got fe34 onto stack
loadstackindirect  -- use address on the stack, to load the value at that address
add.w              -- assumes we already have the other operand on the stack
                   -- result back onto the stack

要计算和加载数组中的值,可能会使用堆栈,因为可能没有索引寻址模式。

所以指令很小,很多工作都是通过堆栈和堆栈指针隐式完成的。 IIRC Transputers 实际上只有三个值的堆栈,编译器(或开发人员)必须确保对其进行维护。

XMOS 现在出售现代“等效”,并雇用一些相同的人。

我写 Transputer 代码已经 20 多年了,抱歉有点含糊。

UCSD Pascal 系统使用了一个软件定义的虚拟机,它是一个堆栈机器。这个想法是要制作一些可移植到新计算机上的东西,而且易于编写、易于编译和合理的性能。它的虚拟机是用它自己的 Pascal 方言定义的。当它被移植到真实的计算机上时,寄存器将用于保存堆栈指针,并且可能会在堆栈顶部的处理方式(通过寄存器)方面进行一些独创性,以获得合理的性能。

【讨论】:

    【解决方案3】:

    那么它必须在汇编级别使用寄存器

    这不是必需的,处理器有一个 cpu 堆栈,其行为很像中间语言中的虚拟堆栈。您可以将指令几乎一对一地转换为 cpu 指令。当然,基于堆栈的 VM 流行的原因之一是抖动很容易实现。

    这样做的唯一问题是机器代码效率不高。抖动优化器的工作是找到有效使用 cpu 寄存器的方法,并以这种方式使代码更快。

    基于寄存器的虚拟机中存在相反的问题。这是一个更难解决的问题,因为真正的 CPU 没有 VM 那么多的寄存器。所以抖动必须想办法使用堆栈溢出硬件不提供的寄存器。

    【讨论】:

      猜你喜欢
      • 2013-11-05
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 2023-01-03
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 2012-01-19
      相关资源
      最近更新 更多