【问题标题】:Storing values in bytecode format以字节码格式存储值
【发布时间】:2015-07-26 13:30:42
【问题描述】:

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

举个例子:

push 4752

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

我试图弄清楚像 JVM 这样的虚拟机是如何做到这一点的,但我无法找到。

【问题讨论】:

    标签: bytecode vm-implementation


    【解决方案1】:

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

    • iconst_ 是将特定值“m1”(-1) 推送到 5 的单个操作码
    • bipush 从指令流中压入下一个字节
    • sipush 从指令流中推送接下来的两个字节
    • ldc 或 ldc_w 从常量池中压入一个 4 字节的值,由指令流中的 index 选择

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

    为了扩展您的问题,JVM 中的long(64 位或 8 字节)值主要是通过推送 int 然后扩大它,或者通过推送来自 long 变量或字段的值(或方法返回)。有一条指令 ldc2_w 从常量池中压入一个 2 单元(8 字节)的值,还有两条专用于频繁使用的指令 lconst_0 和 lconst_1 表示 0 和 1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 2016-11-04
      • 1970-01-01
      • 2019-02-21
      • 1970-01-01
      • 2020-03-19
      相关资源
      最近更新 更多