Java字节码 - 寄存器1包含错误的类型

时间:2014-05-15 19:30:16

标签: java java-bytecode-asm jasmin

我目前遇到以下问题:

尝试执行下面的代码,我得到“包含错误类型的寄存器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)

1 个答案:

答案 0 :(得分: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 

BTW:在深入研究这个问题的过程中,我从jd-gui获得了帮助:您只需将.class文件拖放到反编译窗口,然后查看代码是否有意义。< / p>