Jvm VerifyError堆栈上有内容时字节码中的空堆栈
我有下面的代码,当使用2个print语句运行时会出现错误,但当我只执行一个语句时,它会正常运行。如果我是正确的,ldc只是将字符串推到堆栈上,所以在调用第二个打印行时,它应该仍然在堆栈上有一些内容Jvm VerifyError堆栈上有内容时字节码中的空堆栈,jvm,bytecode,jasmin,Jvm,Bytecode,Jasmin,我有下面的代码,当使用2个print语句运行时会出现错误,但当我只执行一个语句时,它会正常运行。如果我是正确的,ldc只是将字符串推到堆栈上,所以在调用第二个打印行时,它应该仍然在堆栈上有一些内容 .class public test .super java/lang/Object .method public static main([Ljava/lang/String;)V .limit stack 5 .limit locals 3 getstatic java/lang/System
.class public test
.super java/lang/Object
.method public static main([Ljava/lang/String;)V
.limit stack 5
.limit locals 3
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "this would work if only this line was printed"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
ldc "but when trying to print this it says it's not on stack?"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
return
.end method
错误:
java.lang.VerifyError: (class: test, method: main signature: ([Ljava/lang/String;)V) Unable to pop operand off an empty stack
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetMethodRecursive(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main"
要执行
invokevirtual
,您需要一个对象来调用其上的方法,也称为方法接收器。与使用getstatic
推送的PrintStream
类似。要执行两个invokevirtual
指令,不仅需要两个参数,还需要两个接收器在第二次调用printstream之前再次调用code>?这是实现这一点的一种方法(最简单)。只需按照getstatic、ldc、invokevirtual
模式执行两次。比如System.out.println(“一”);System.out.println(“两个”)代码>将在源代码中执行。或创建等效于PrintStream tmp=System.out的文件;tmp.println(“一”);tmp.println(“两个”)代码>。我建议您阅读JVM规范。@Sten该页上的“(c)…July 1996”应该会告诉您一些事情。正如在回答您的另一个问题时所说,Jasmin已经十年没有更新了(事实上,由于过时的CVS存储库,sourceforge甚至不再支持更新)。你在这里骑死马了。包含你需要知道的一切。但是请记住,a)没有关于程序集语法的官方标准,因此Jasmin可能有细微的差异,b)Jasmin不支持更新的功能。要执行invokevirtual
,您需要一个对象来调用方法,也称为方法接收器。与使用getstatic
推送的PrintStream
类似。要执行两个invokevirtual
指令,不仅需要两个参数,还需要两个接收器在第二次调用printstream之前再次调用code>?这是实现这一点的一种方法(最简单)。只需按照getstatic、ldc、invokevirtual
模式执行两次。比如System.out.println(“一”);System.out.println(“两个”)代码>将在源代码中执行。或创建等效于PrintStream tmp=System.out的文件;tmp.println(“一”);tmp.println(“两个”)代码>。我建议您阅读JVM规范。@Sten该页上的“(c)…July 1996”应该会告诉您一些事情。正如在回答您的另一个问题时所说,Jasmin已经十年没有更新了(事实上,由于过时的CVS存储库,sourceforge甚至不再支持更新)。你在这里骑死马了。包含你需要知道的一切。但是请记住,a)没有关于汇编语法的官方标准,因此Jasmin可能有细微的差异,b)Jasmin不支持更新的功能。