我正在开发一个实验性虚拟机,现在我为每种类型的所有数据类型操作都有一个单独的指令,只是为了安全起见。例如。我有8,16,32和64位有符号和无符号整数的ADD指令,以及float,double和long double。这是一个操作的11条指令。现在确实有些操作只支持某些类型,但即便如此,我最终会得到很多指令而且只有很少的空间。
所以我想知道一些指令是否可以操作而不管底层类型,所以我可以减少数量并为将来我将迫切需要的更多指令腾出空间,因为我不想超过指令的一个字节。
答案 0 :(得分:1)
不是让每个数据类型都有ADD
,SUB
等,而是为什么不让它们对“寄存器”进行操作,并且对所有将为零的数据类型都有MOV
之类的指令out / sign扩展寄存器的其余部分(如果有的话)。
这当然是假设您在VM中有类似的东西。您可能希望在问题中添加更多信息。
答案 1 :(得分:1)
除非每个表达式在运行时都带有自己的类型信息,否则您没有太多的选择。
真正的处理器如何实现它是一个操作码,然后是一种操作数代码,它告诉处理器使用哪种操作数。例如,您可能会说
enum Operator {
Add,
Sub,
And,
...
};
enum Operand {
Memory,
Immediate,
Reg1,
Reg2,
...
};
struct Instruction {
Operator op;
Operand lhs;
Operand rhs;
};
另外,像add和sub这样的指令不需要知道signed和unsigned之间的区别。这是2补码的优势之一。
通常,每个寄存器具有固定宽度(例如x86为32位),然后如果要操作最低的8位,则首先使用AND操作屏蔽其他24。当然,在x86上,我认为在某些情况下你仍然可以使用8位,16位寄存器来指代32位寄存器的部分。
答案 2 :(得分:0)
Java VM仅针对类型ADD
(64),SUB
(64 fp)和{{long
,double
等某些操作来解决此问题。 1}}(32)。然后,它提供了许多转换指令,用于将32位类型转换为16位和8位(有符号和无符号)。
当然,如果所需的转换操作数量少于您最后使用的操作数量(如果您有特殊的int
,ADD
,{{1}每种类型都有,SUB
等。
如果需要添加两个16位变量,则使用MUL
指令将它们移至32位寄存器,并执行32位DIV
。然后你取结果并用16_to_32
位操作将其转换为16位变量位,该操作截断结果以适合16位变量。
您的ADD_32
说明可以处理签名或无符号转换所需的符号扩展或零扩展。
如果你对jvm如何看待jvm spec感兴趣。