2014-10-27 30 views
1

基于堆栈的和基于寄存器的虚拟机如何处理不同的数据类型?基于(堆栈/注册)的虚拟机如何处理不同的数据类型

我知道基于堆栈的虚拟机使用堆栈来存储他们的数据以及在这个堆栈上和下来推送和弹出数据,但他们如何表示这些数据?是否像某种数据可以被转换为任何需要的数据或有多个堆栈,每个数据类型一个堆栈,例如ints,浮点数,对象,字符,数组和引用?如果它使用多个堆栈,那么它是否必须移动东西才能添加说float和int?

另外,基于注册的虚拟机做类似的事情吗?

如果许多虚拟机以不同的方式运行,那么JVM和Dalvik虚拟机就是很好的例子。

在此先感谢。

+2

堆栈中的数据被解释*的方式通常取决于所执行的操作码。例如,当有些人可以使用堆栈项目时,有些专用于字节或短操作。堆栈总是存储相同类型的数据,可能是很长的一段时间。 – Seki 2014-10-27 08:37:28

+0

@Seki,所以它们的数据类型与您的说法完全相同,但是它们是通过不同的操作码进行转换或用作不同类型的? – zeitue 2014-10-27 14:50:09

+0

调查[neokvm](http://nekovm.org/)和[lua](http://lua.org/)。两者都是简单的虚拟机,并且源代码是免费软件。 – 2014-10-27 14:50:12

回答

1

大多数字节码解释器和虚拟机做的是要么...

你可以使用一个工会位转换成不同的类型,例如在转变双到字符数组

union { 
    uint32_t i[2]; 
    double dbl; 
} dbl2ints; 

dbl2chars.dbl = double_value; 

您现在可以使用dbl2chars.i[0]dbl2chars.i[1]中的值将其嵌入任何存放虚拟机内存/数据的内容中。因此,如果您的自定义语言编译为VM字节码,则可以让编译器将浮点数/双精度值编译为整数值并使用正确的浮点操作码,然后将这些位重新解释为浮点数/双精度值。

另一种更流行的方法(如Lua的VM和其他VM所使用的)是制作标记的联合。

typedef union { 
    float fl; 
    uint32_t ui; 
    char *pstr; 
} valuedata; 

typedef struct { 
    valuedata val; 
    uint32_t valtype; 
} ValType; 
0

基于堆栈和基于寄存器的虚拟机实际上都以相同的方式存储其数据。基于寄存器的虚拟机使用一组32位或64位字长的字(无符号整数)来表示它们的寄存器。对于基于堆栈的虚拟机,堆栈实现为一个单词数组,通常是32位无符号整数,指向数组堆栈顶部的指针。

这些类型的虚拟机实际存储和处理数据的诀窍是读取和写入数据时。例如,要将double加载到基于32位堆栈的虚拟机的堆栈中,这个double将分为两部分。 double的上半部分和下半部分将被视为无符号整数,并简单地单独推入堆栈。这些类型的数据转换可以通过C和C++中的转换,指针和联合来实现。

相关问题