Assembly 汇编语言-堆栈机

Assembly 汇编语言-堆栈机,assembly,x86,masm,Assembly,X86,Masm,我在业余时间学习汇编语言,以成为一名更好的开发人员 我从概念上理解了基于堆栈的机器和基于寄存器的机器之间的区别,但我想知道基于堆栈的机器实际上是如何实现的。如果虚拟机(例如JVM或.NET)在基于寄存器的体系结构(例如x86或x64)上运行,那么它必须在程序集级别使用寄存器(就我而言)。很明显,我遗漏了一些东西。因此,我不确定汇编语言的区别 我在这里读过文章,比如维基百科,但我不相信他们能直接回答我的问题。基于堆栈的机器很少用硬件实现——我只听说过一个这样的实现,而且从来没有机会使用过 实际上,

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

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


我在这里读过文章,比如维基百科,但我不相信他们能直接回答我的问题。

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

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

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

问:那为什么是间接的呢? 可移植性-堆栈机器的指令集可以在任意数量的基于寄存器的机器上模拟。这意味着同一个JVM应用程序可以在任何有解释器的机器上运行,因此Java的口号是“写一次,在任何地方运行”

然后它必须在程序集级别使用寄存器

这不是一个要求,处理器有一个cpu堆栈,其行为非常类似于中介语言中的虚拟堆栈。您可以将指令几乎一对一地转换为cpu指令。当然,基于堆栈的虚拟机流行的原因之一是抖动很容易实现

这样做的唯一障碍是机器代码不是很有效。抖动优化器的任务是找到有效使用cpu寄存器的方法,并以这种方式加快代码的速度

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

供参考,它们是堆栈机器。具有如此灵活的寻址模式,可以用作堆栈机。我想这可能是一台堆垛机(20多年前,我的脑子在打滑:-)

它们实际上在指令中没有任何寄存器名/编号来查找操作数,因为它们位于堆栈上

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

因此,他们没有
add.wr0,r1,r5
add.weax,[#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 Transputer实际上只有一个只有三个值的堆栈,编译器(或开发人员)必须确保该堆栈得到维护

现在,出售一个现代的“等价物”,雇佣一些同样的人

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


系统使用软件定义的虚拟机,即堆栈机。这个想法是为了制造一种可以移植到新电脑上的东西,而且也易于编写,易于编译,性能合理。它的虚拟机是用自己的帕斯卡方言定义的。当它被移植到真正的计算机上时,寄存器将被用来保存堆栈指针,并且可能在如何(通过寄存器)处理堆栈顶部方面有一些独创性,以便获得合理的性能

你所说的“本地翻译”是什么意思。你指的是JIT编译器吗(在.NET的情况下)?“本机解释器”指的是运行在本地机器上读取堆栈机器指令的应用程序执行它们。每种类型的机器(和操作系统)都有不同的“本机解释器”。对于Java,“本机解释器”是JVM。JIT是稍有不同的。仅供参考,JIT是将堆栈机器指令转换为本地机器的等效指令集(基于寄存器的指令集)。这是为了给应用程序提供接近本机处理器的性能,但同时保持可移植性的优势。Hans Passant@本机处理器确实不需要使用寄存器,但实际上1)寄存器比堆栈快得多,因此,对于性能,您可能希望。2) 在许多基于CISC的处理器上,并非所有指令都可以在堆栈数据上执行。必须先将数据加载到寄存器中,然后才能对其进行操作。也就是说,由解释器开发人员决定如何实现这些指令。谢谢。你提到一个解释器,这让我有点困惑,因为我知道.NET和Java是编译语言;与PHP不同,PHP是经过解释的。你能澄清一下吗?再次感谢。他们可以在软件中模拟它,旧的JVM就是这么做的。通常,尽管堆栈机器代码被编译为本机代码(不管是什么体系结构)。堆栈机器码很好,因为它有一个简洁的编码,它很容易从ASTs生成,并且相对容易分析。