【问题标题】:Does the instruction istore start at index 1 in the main method?指令 istore 是否从 main 方法中的索引 1 开始?
【发布时间】:2020-02-12 14:49:39
【问题描述】:

给定指令istore_<n> 及其documentation

n 必须是当前帧的局部变量数组的索引(第 2.6 节)。

它没有指定它从哪个索引开始。我假设为 0。对于给定的 istore 操作,它应该增加 1。

给定一个简单的类:

public class TestingStuff {
    public static void main(String[] args) {
        int a = 11;
        int b = 12;

    }

    public static void test() {
        int c = 13;
        int d = 14;
    }
}

我希望这两种方法有不同的框架。那么这应该意味着存储ab 的指令将是istore_0istore_1。以及用于存储cd 的相同索引。但由于某种原因,main 方法中的索引从1 开始。这似乎总是如此。但我找不到任何有关原因的信息。

来自 javap 的输出:

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=3, args_size=1
         0: bipush        11
         2: istore_1
         3: bipush        12
         5: istore_2
         6: return

  public static void test();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=2, args_size=0
         0: bipush        13
         2: istore_0
         3: bipush        14
         5: istore_1
         6: return

是这样吗?如果有,为什么?

【问题讨论】:

    标签: java jvm jvm-bytecode javap


    【解决方案1】:

    静态方法的参数从位置0开始作为局部变量传递。因此,对于mainargs数组在本地位置 0 处的变量。编译使用 args 执行某些操作的代码应该可以证明这一点,尽管我手边没有编译器。

    (例如方法,this 在位置 0,然后其余参数从位置 1 开始。)

    详情请见section 2.6.1

    【讨论】:

    • 我在使用 args 时唯一看到的是使用了 iload_0。但我从未见过istore_0。但是如果我为测试方法创建一个参数,我会看到c 是通过istore_1 推送的。所以现在一切都说得通了(期待第一个 istore_0 用于 main 方法参数)。
    • @gel:没有。它在方法开始时自动加载到没有特定字节码中。
    • 请注意,由于args 没有在示例main 方法中使用,编译器可以 使用istore_0,消除args 变量并重用槽对于新变量,但常见的编译器不这样做。
    猜你喜欢
    • 2013-01-01
    • 1970-01-01
    • 2016-12-27
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    相关资源
    最近更新 更多