我正在开发一个实验性的VM,为了安全起见,现在我对每种类型的所有数据类型操作都有一个单独的指令。例如,我有一个8位,16位,32位和64位有符号和无符号整数的加法指令,以及浮点数,双精度和长双精度的指令。这是一次操作的11条指令。现在确实有些操作只支持某些类型,但即便如此,我最终还是得到了很多指令和很少的空间。
所以我想知道是否一些指令可以操作而不考虑下面的类型,所以我可以减少数量,为更多的指令腾出空间,因为我不想超过指令的一个字节。
发布于 2013-08-10 23:03:43
而不是使用ADD、SUB等。对于每种数据类型,为什么不让它们在“寄存器”上操作,并对所有数据类型使用类似MOV的指令,这些指令将对寄存器的其余部分(如果有的话)进行置零/符号扩展。
当然,这是假设您的VM中有类似的东西。您可能希望在您的问题中添加更多信息。
发布于 2013-08-10 23:10:00
您没有太多的选择,除非每个表达式在运行时都带有自己的类型信息。
真正的处理器如何做到这一点是有一个操作码,然后是一种操作数代码,它告诉处理器使用哪种操作数。例如,你可以说
enum Operator {
Add,
Sub,
And,
...
};
enum Operand {
Memory,
Immediate,
Reg1,
Reg2,
...
};
struct Instruction {
Operator op;
Operand lhs;
Operand rhs;
};而且,像add和sub这样的指令不需要知道有符号和无符号之间的区别。这是2的补码的优点之一。
通常,每个寄存器的宽度都是固定的(例如,对于x86为32位),然后,如果您想对最低的8位进行操作,则首先使用and操作屏蔽其他24位。当然,我认为在某些情况下,在x86上仍然可以使用8位、16位寄存器来引用32位寄存器的一部分。
发布于 2013-08-10 23:22:58
Java只支持特定的操作,如long (64)、double(64 fp)和int (32)类型的ADD、SUB,从而解决了这个问题。然后,它提供许多转换指令,将32位类型转换为16位和8位(有符号和无符号)。
当然,这种方法只有在所需的转换操作数量少于您为每种类型指定特殊的ADD、SUB、MUL、DIV等操作的数量时才有优势。
如果需要添加两个16位变量,您可以使用16_to_32指令将它们移至32位寄存器,并执行32位ADD_32。然后使用32_to_16位操作将结果转换为16位变量,该操作将结果截断以适合16位变量。
然后,您的x_to_y指令可以处理有符号或无符号转换所需的符号扩展或零扩展。
如果您对jvm是如何做到这一点感兴趣的,可以看看jvm spec。
https://stackoverflow.com/questions/18163105
复制相似问题