The next example is a method that takes an int. If it's greater than 20, the method returns the string "i > 20"; otherwise, it returns the string "i <= 20".
.method static compareTo20(I)Ljava/lang/String; ;load_0 ; Push variable i from slot 0 bipush 20 ; Push the number 20 if_icmpgt greater ; Go to the code at label "greater" ; if i > 20 ; Execution continues here if the i <= 20 ldc "i <= 20" areturn greater: ; This is the "greater" label ; Execution continues here if i > 20 ldc "i > 20" areturn .end method
The goto instruction does a transfer no matter what. They're most often used to write loops like the following one, which loops until variable 0 reaches 21:
loop: ; Begin the loop iload_0 ; Push variable i (in slot 0) bipush 20 ; Push 20 if_icmpgt break ; Break the loop if i>20 iinc 0 1 ; Increment i by 1 goto loop ; And go back to the beginning of the loop break: ; Go here after looping
The if instructions break down into three groups. The first group is used to compare ints to other ints. The mnemonics for these instructions are if_icmpgt, if_icmplt, if_icmpge, if_icmple, if_icmpeq, or if_icmpne. The last two letters of these instructions stand for "greater than," "less than," "greater than or equal to," "less than or equal to," "equal to," and "not equal to," respectively.
For example, if you wanted to loop until i was equal to 20 instead of greater than 20:
loop: ; Begin the loop iload_0 ; Push variable i bipush 20 ; Push 20 if_icmpeq break ; Break the loop if i == 20 iinc 0 1 ; Increment i by 1 goto loop ; And go back to the beginning of the loop break: ; Go here after looping
The second group of branch instructions is like the first, except that instead of taking two ints and comparing them, they take one int and compare it to zero. The mnemonics for the instructions begin with if and end with the same suffix used for the first set. For example,
iconst_m1 ; Push -1 ifle less_than_zero ; Goes to less_than_zero ; since -1 <= 0 bipush 42 ; Push 42 bipush 26 ; Push 26 isub ; Subtract 26 from 42, leaving 16 ifeq same_as_zero ; Goes to the next instruction, since ; 16 != 0
The compare-to-zero instructions are frequently used with boolean values, where 0 means false and 1 means true. For example,
aload_1 ; Push a Double object invokevirtual java/lang/Double/isInfinite ()Z ; returns 1 if the number is infinite, ; and 0 otherwise ifne infinity ; Go to infinity if the number is infinite
Branches may jump only within a single method. You're not allowed to branch to code outside a method. For example, this is illegal:
.method doSomething()V loop: ;; Loop code goes here goto loop .end method .method bigBranch()V goto loop ; Illegal! return .end method .method someOtherMethod
If you try this, the Oolong assembler will report that the loop label is not found.
Labels have a lifespan only within the method. Because of this, you can use the same label several times in a single class:
.method methodOne()V loop: ;; Loop code goes here goto loop .end method .method methodTwo()V loop: ;; More loop code goes here goto loop .end method