Search code examples
javajvmstackjasmin

Inconsistent stack height 1 !=2


so I'm trying to make a simple for loop in Jasmin that prints out hello world everytime it goes through the loop. The problem is whenever I try to increment it by adding one I get this error that says, "Error: Unable to initialize main class test Caused by: java.lang.VerifyError: (class: test, method: main signature: ([Ljava/lang/String;)V) Inconsistent stack height 1 != 2" It works when I'm not trying to add one, but not sure why it doesn't when I put it back in. Any help would be appreciated!

.class public test
.super java/lang/Object

.method public <init>()V
   aload_0
   invokenonvirtual java/lang/Object/<init>()V
   return
.end method

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

   ldc 15
   ldc 1
startLoop:
   iflt endLoop
   getstatic java/lang/System/out Ljava/io/PrintStream;
   ldc "hello world"
   invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
   ldc 1
   iadd
   goto startLoop
endLoop:
   return
.end method

Solution

  • Your code ends up with a different stack height depending on whether you go to endLoop immediately on the first iteration (the verifier doesn't check or see that your value is never smaller than zero) or whether you have gone through the loop.

    Keep in mind that iflt compares the top of the stack with zero and if it is less than zero , it goes to endLoop. In the process, it removes the value from the top of the stack.

    After your first iflt, it removed the value 1 from the top of the stack. Then it adds 1 to 15, leaving the value 16 on the stack.

    The next iflt pops the value 16 from the stack - on he next iteration the iadd would fail because there is only one value on the stack (1) and iadd needs two.

    As a solution, you probably want to use if_icmpge to check if your counter is greater than 15, And for every comparison, you first want to dup your counter and then push the constant 15 on the stack.