0

我目前陷入以下问题:

尝试执行下面的代码,我收到“寄存器 1 包含错误类型”的 java 错误。由于我只使用 1 个堆栈块整数,我真的想知道错误类型是如何进入该寄存器的。下面是我的 jasmin-java-bytecode,它编译得很好,但是在执行时会抛出该错误。

.class public HelloWorld .super java/lang/Object

.method public static fakultaet(I)I
 .limit locals 100
 .limit stack 100

ldc 4

istore 0


ldc 1

istore 2
START: 
iload 0

iload 2

isub 
ifne ENDE 
iload 0

ldc 1

imul
istore 1

iload 2

ldc 1

iadd
istore 2

goto START 
ENDE: 
getstatic java/lang/System/out Ljava/io/PrintStream;
iload 1

invokevirtual java/io/PrintStream/println(I)V

iload 1
ireturn


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



ldc 1

istore 0


ldc 2.0

fstore 1


ldc 3

istore 2

ldc 3

ldc 2

iadd
istore 0

ldc 3

invokestatic HelloWorld/fakultaet(I)I

return 

.end method

这是生成的错误:

Exception in thread "main" java.lang.VerifyError: (class: HelloWorld, method: fakultaet signature: (I)I) Register 1 contains wrong type
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2451)
    at java.lang.Class.getMethod0(Class.java:2694)
    at java.lang.Class.getMethod(Class.java:1622)
    at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
4

1 回答 1

0

我对 Jasmin 不太熟悉(嗯...软件),但这里似乎有几个问题:您正在存储到寄存器 1,尽管它可能尚未初始化。添加

ldc 1
istore 1

至少在你的标签前面START使它编译和加载类。

但它仍然只打印1不是想要的结果。据我所知,条件

ifne ENDE 

实际上应该是

ifeq ENDE 

因为你想在计数器和参数之间的差异不为零运行循环(所以它应该在计数器和参数相等时结束,即当它们的差异为零时)。

此外,以下部分(实际循环)

...
ifeq ENDE 
iload 0
ldc 1
imul
istore 1
iload 2
ldc 1
iadd
istore 2
goto START 

继续将参数乘以 1。您可以/应该改为增加计数器,并在每次传递中将结果与此计数器相乘:

...
ifeq ENDE 
iload 2
ldc 1
iadd
istore 2
iload 1
iload 2
imul
istore 1
goto START 

顺便说一句:在深入研究时,我从jd-gui获得了帮助:您可以将文件拖放.class到反编译器窗口中,然后查看代码是否有意义。

于 2014-05-15T20:25:28.590 回答