Java ';主要';方法指向';args';而不是';这个';?
我试图实现Java的一个子集,用于学术研究。嗯,我已经进入最后阶段(代码生成),我编写了一个相当简单的程序来了解如何处理方法参数:Java ';主要';方法指向';args';而不是';这个';?,java,jvm,bytecode,instructions,jasmin,Java,Jvm,Bytecode,Instructions,Jasmin,我试图实现Java的一个子集,用于学术研究。嗯,我已经进入最后阶段(代码生成),我编写了一个相当简单的程序来了解如何处理方法参数: class Main { public static void main(String[] args) { System.out.println(args.length); } } 然后我构建了它,并通过在线反汇编程序运行了“Main.class”,我在: 我得到了“main”方法的以下实现: (分解后的输出用Jasmin表示)
class Main {
public static void main(String[] args) {
System.out.println(args.length);
}
}
然后我构建了它,并通过在线反汇编程序运行了“Main.class”,我在:
我得到了“main”方法的以下实现:
(分解后的输出用Jasmin表示)
我的问题是:1.
aload_0
应该将“this”推到堆栈上(JVM规范似乎是这么说的)2.
arraylength
应该返回引用位于堆栈顶部的数组的长度
因此,根据我的观点,1和2的组合甚至不应该起作用
它如何工作/为什么工作?或者是反汇编程序有缺陷,而实际的字节码是其他东西
aload_0应该将“this”推送到堆栈上
不完全…aload_0
读取方法的第一个引用参数(或者更一般地说,第一个局部引用变量)并将其推送到堆栈上
在成员函数中,第一个局部变量恰好是this
引用
但是
main
不是一个成员函数,它是一个静态函数,因此没有这个
参数,方法的第一个真正参数是args
,这对所有静态方法都适用吗?@KonradRudolph-不要认为上面的说法是正确的aload_0
读取调用此方法的实例(即this
变量),并aload_1
读取此方法的第一个参数(从当前帧的局部变量数组并推送到操作数堆栈上)。参考SE8的JVM文档(也参考第2.6节)[@BuckCherry和静态方法会发生什么?有关说明,请参阅第一条注释“grinch”。@grinch-I ready没有得到this.foo(x,y)实际上是foo.foo(this,x,y)
。你是说对于静态方法,aload_0将当前类读取到堆栈上!!@KonradRudolph-从概念上讲,JVM不需要知道哪个索引存储什么。但是,JVM(SE8)确实要求行为以及静态和非静态方面。摘自规范第2.6.1节-“在类方法调用时,从局部变量0开始,在连续的局部变量中传递任何参数。在实例方法调用时,始终使用局部变量0传递对调用实例方法的对象的引用(在Java编程语言中是这样)…”
.method public static main([Ljava/lang/String;)V
.limit locals 1
.limit stack 2
getstatic java/lang/System/out Ljava/io/PrintStream;
aload_0
arraylength
invokevirtual java/io/PrintStream.println(I)V
return
.end method