基于堆栈和基于寄存器的虚拟机如何处理不同的数据类型?
我知道基于堆栈的虚拟机使用堆栈来存储数据,并在此堆栈上推送和弹出数据,但它们如何表示这些数据?它是否像某种数据可以转换为需要的或者有多个堆栈,每个数据类型有一个堆栈,如整数,浮点数,对象,字符,数组和引用?如果它使用多个堆栈,那么它是否必须移动东西才能添加一个浮点数和一个int?
另外,基于寄存器的虚拟机是否也做类似的事情?
如果许多虚拟机以不同的方式执行操作,那么JVM和Dalvik VM就是很好的例子。
提前致谢。
答案 0 :(得分:2)
大多数字节码解释器和VM所做的是......
您可以使用联合将位转换为不同的类型,例如将double转换为chars数组
union {
uint32_t i[2];
double dbl;
} dbl2ints;
dbl2chars.dbl = double_value;
现在,您可以使用dbl2chars.i[0]
和dbl2chars.i[1]
中的值来放入持有虚拟机内存/数据的任何内容。因此,如果您的自定义语言编译为VM字节码,您可以让编译器将浮点数/双精度编译为整数值并使用正确的浮点操作码,然后将这些位重新解释为浮点数/双精度数。
另一种更受欢迎的方法(由Lua的VM和其他虚拟机使用)是制作标记的联合。
typedef union {
float fl;
uint32_t ui;
char *pstr;
} valuedata;
typedef struct {
valuedata val;
uint32_t valtype;
} ValType;
答案 1 :(得分:0)
基于堆栈和基于寄存器的虚拟机实际上都以相同的方式存储数据。基于寄存器的虚拟机使用所选字长的字数组(无符号整数),如32或64位来表示它们的寄存器。对于基于堆栈的虚拟机,堆栈实现为一个字数组,通常是32位无符号整数,带有指向数组堆栈顶部的指针。
这些类型的虚拟机实际存储和处理数据的技巧是在读取和写入数据时。例如,为了将双重打开到32位基于堆栈的虚拟机的堆栈,可以分两部分读取double。 double的上半部分和下半部分将被视为无符号整数,并且可以单独将其推入堆栈。这些类型的数据转换可以通过C和C ++中的转换,指针和联合来实现。