以字节码格式存储值

时间:2015-07-26 13:30:42

标签: bytecode vm-implementation

我用Java创建了一个原型VM(因为它是我最熟悉的语言),我试图以字节码格式存储指令。我想知道如何在字节码中存储值,因为 byte s只能是0到255。

举个例子:

push 4752

Push将使操作码值为0。 但我怎么能存储4752?它不适合单个字节。 我可以将值存储在4个字节中,因此允许它们为32位整数,但是我必须决定加载操作码(1个字节)或值(4个字节)。目前我将程序作为整数数组传递,VM循环遍历数组并执行操作码。如果操作码需要一个值,它从数组中获取它,然后增加程序计数器以跳过该值,这样它就不会被执行。

我试图找出像JVM这样的虚拟机如何做到这一点,但我无法找到答案。

1 个答案:

答案 0 :(得分:3)

JVM有几个选项允许对预期更频繁的案例进行较小的编码,因此平均较小的方法和类编码。具体请参阅下面的说明 https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5(或se8,但是IIRC没有基本的算术/计算指令在7和8之间改变,只有一个或两个调用指令):

  • iconst_< i> 是推送特定值“m1”( - 1)到5
  • 的单个操作码
  • bipush 从指令流中推送下一个单字节
  • sipush 从指令流中推送下两个字节
  • ldc ldc_w 从常量池中推送一个四字节值,由指令流中的索引选择

您的示例值4752适合两个字节,并使用 sipush

要扩展您的问题,JVM中的long(64位或8字节)值主要是通过推送int然后加宽它,或者通过推送{{1变量或字段(或方法返回)。有一条指令 ldc2_w 用于从常量池中推送2个单元(8字节)的值,以及两个特殊频率指令 lconst_0 lconst_1 为0和1。