0

当前情况和背景

对于学校作业,我们必须编写自己的编程语言。目前,我一直在尝试进行方法调用。

我可以成功地创建一个方法,但是在我试图调用它的时候,程序中断了。

测试代码

我用来测试的代码是

testMethod();

method testMethod () {
    print("Test");
}

这会生成以下代码

  • 反编译类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// AS YOU CAN SEE IT CAN NOT DECOMPILE MAIN METHOD
//

public class test {
    public static void main(String[] param0) {
        // $FF: Couldn't be decompiled
    }

    public void testMethod() {
        System.out.println("Test");
    }
}

  • Java字节码
.class public test
.super java/lang/Object

.method public static main([Ljava/lang/String;)V
.limit stack 99
.limit locals 99

invokevirtual void/testMethod()V
return
.end method
.method public testMethod()V
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Test"
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
.limit stack 10
.limit locals 10
return
.end method

我试过什么

我尝试使用以下 Java 字节码调用该方法:

(测试是我正在测试的类的名称)

  • 调用虚拟 void/testMethod()V
  • 调用虚拟测试方法()V
  • 调用虚拟测试/testMethod()V
  • 调用虚拟测试/void/testMethod()V

我很感激任何帮助

4

1 回答 1

1

正如评论中@apangin 所解释的,您正在尝试调用一个实例方法,因此您需要一个对象来调用它,但您没有提供一个对象。您需要test在调用之前创建一个实例并将其推送到堆栈中testMethod,或者标记testMethod为静态并通过调用它invokestatic,这在这种情况下可能更容易。

话虽如此,我还建议使用Krakatau 汇编程序而不是 Jasmin。Krakatau 使用 Jasmin 语法的略微修改形式,它更简单且不易出错。特别是在 Krakatau 中,类名、方法名和方法描述符由空格分隔,消除了您在调用方法时需要在何处放置斜杠的许多困惑。Krakatau 还具有其他优势,例如完全支持包括 Java 14 功能在内的字节码格式,以及一个往返反汇编程序,可以极大地帮助解决字节码相关问题。

于 2020-08-10T14:02:16.337 回答