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



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

我知道基于堆栈的虚拟机使用堆栈来存储数据,并在堆栈中推送和弹出数据,但它们如何表示这些数据?它是像某种可以转换为所需内容的数据,还是有多个堆栈,每个数据类型(如int、float、对象、字符、数组和引用)都有一个堆栈?如果它使用了多个堆栈,那么它是否必须四处移动才能添加float和int?

此外,基于注册的虚拟机也有类似的功能吗?

JVM和Dalvik虚拟机将是一个很好的例子,如果许多虚拟机的做法不同的话。

提前谢谢。

大多数字节码解释器和VM所做的是。。。

您可以使用并集将位转换为不同的类型,例如将double转换为字符数组

union {
    uint32_t i[2];
    double dbl;
} dbl2ints;
dbl2chars.dbl = double_value;

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

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

typedef union {
    float fl;
    uint32_t ui;
    char *pstr;
} valuedata;
typedef struct {
    valuedata val;
    uint32_t valtype;
} ValType;

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

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

最新更新