我用Java创建了一个原型VM(因为它是我最熟悉的语言),我试图以字节码格式存储指令。我想知道如何在字节码中存储值,因为 byte s只能是0到255。
举个例子:
push 4752
Push将使操作码值为0。 但我怎么能存储4752?它不适合单个字节。 我可以将值存储在4个字节中,因此允许它们为32位整数,但是我必须决定加载操作码(1个字节)或值(4个字节)。目前我将程序作为整数数组传递,VM循环遍历数组并执行操作码。如果操作码需要一个值,它从数组中获取它,然后增加程序计数器以跳过该值,这样它就不会被执行。
我试图找出像JVM这样的虚拟机如何做到这一点,但我无法找到答案。
答案 0 :(得分:3)
JVM有几个选项允许对预期更频繁的案例进行较小的编码,因此平均较小的方法和类编码。具体请参阅下面的说明 https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5(或se8,但是IIRC没有基本的算术/计算指令在7和8之间改变,只有一个或两个调用指令):
您的示例值4752适合两个字节,并使用 sipush 。
要扩展您的问题,JVM中的long
(64位或8字节)值主要是通过推送int
然后加宽它,或者通过推送{{1变量或字段(或方法返回)。有一条指令 ldc2_w 用于从常量池中推送2个单元(8字节)的值,以及两个特殊频率指令 lconst_0 和 lconst_1 为0和1。