【问题标题】:How do (stack/register) based virtual machine handle different datatypes基于(堆栈/寄存器)的虚拟机如何处理不同的数据类型
【发布时间】:2014-10-27 02:43:54
【问题描述】:

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

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

除了基于寄存器的虚拟机做类似的事情吗?

如果许多 VM 的做法不同,那么 JVM 和 Dalvik VM 就是很好的例子。

提前致谢。

【问题讨论】:

  • 堆栈中的数据解释的方式通常取决于执行的操作码。例如,有些专用于字节或短操作,而有些则可以将堆栈项用作长。堆栈总是存储相同类型的数据,可能很长。
  • @Seki 所以它们都是相同的数据类型,就像你说的那样,但是它们被不同的操作码转换或用作不同的类型?
  • 查看neokvmlua。两者都是简单的虚拟机,源代码是免费软件。

标签: c types jvm stack vm-implementation


【解决方案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;

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-11-20
      • 2012-01-31
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 2014-05-18
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多