Brought to you by EarthWeb
ITKnowledge Logo Login Graphic Click Here!
Click Here!
ITKnowledge
Find:
 
EXPERT SEARCH ----- nav

EarthWeb Direct

EarthWeb sites: other sites

Previous Table of Contents Next


Comparison instructions

There are 17 comparison instructions. Java has the most direct support for comparisons on ints. There are five instructions that compare the int on the top of the stack to zero and branch accordingly. There are five more instructions that compare the top two ints on the stack and branch accordingly. There are five comparison instructions that compare the top two longs, floats, or doubles on the stack and push a 1 or 0 onto the stack, depending on the result. Finally, there are two instructions that compare references for equality and branch depending on the result.

In all cases where the result of a comparison is a branch, the two bytes immediately following the comparison instruction are a signed short giving the relative position in the code array to which it should branch. Positive values mean a jump forward. Negative values mean a jump backward. For example, consider this instruction:

     12  if_icmplt
     13 -1
     14 -7

Here the top two ints on the stack are popped and compared. If the second word popped is less than the first word popped, then control branches back seven bytes before byte 12. If the second int popped is not less than the first int popped, then control moves forward to byte 15, the next instruction after if_icmplt.

Compare int to zero

Six instructions compare the int on the top of the stack to 0:


ifeq branch if equal to zero
ifne branch if not equal to zero
iflt branch if less than 0
ifge branch if greater than or equal to zero
ifgt branch if greater than 0
ifle branch if less than or equal to 0

The first two, ifeq and ifne, are used primarily to add a branch after a comparison between two longs, floats, or doubles. For example, consider the following method and its byte code equivalent:

     public int compare() {

      double d1 = 5.6;
      double d2 = 7.8;
      if (d1 > d2) {
       return 3;
      }
      else {
       return 5;
      }

     }

     public int compare() {

    0   ldc2_w
    1   0
    2   6
    3   dstore_1
    4   ldc2_w
    5   0
    6   9
    7   dstore_3
    8   dload_1
    9   dload_3
    10  dcmpl
    11  ifle
    12  0
    13  5
    14  iconst_3
    15  ireturn
    16  iconst_5
    17  ireturn

     }

The two doubles, 5.6 and 7.8, are compared with the dcmpl instruction in line 10. The result of that comparison, a 0 or a 1, is pushed onto the stack. Then instruction 11, ifle, pops the result off the stack. If it’s less than or equal to zero, execution branches ahead five bytes to byte 16, and 5 is returned. Otherwise, control continues with instruction 14, and 3 is returned.

Comparing two values

Suppose that the top of the stack holds two int values, as shown in Figure 5-42. There are six instructions that pop these two ints and branch depending on how they compare.


Figure 5-42  A stack with two int values.


if_icmpeq branch if int1 equals int2
if_icmpne branch if int1 does not equal int2
if_icmplt branch if int2 is less than int1
if_icmpge branch if int2 is greater than or equal to int1
if_icmpgt branch if int2 greater than int1
if_icmple branch if int2 less than or equal to int1

Comparisons between non-int data types aren’t as common, so there are fewer instructions to handle all the different cases. Therefore, comparisons between non-int data types often take longer and result in larger code sizes.

There is exactly one instruction to compare two longs: lcmpl. It pops two longs from the stack. If the two longs are equal, lcmpl pushes zero back onto the stack. If they’re not equal and the first long is greater than the second long popped, then -1 is pushed onto the stack. Finally, if the second long popped is greater than the first long popped, 1 is pushed onto the stack. Depending on the actual comparison that was made in the source code, one of the ifeq, ifne, ifgt, ifge, iflt, or ifle instructions would normally be used to test this value and decide whether to branch.

The fcmpl, fcmpg, dcmpl, and dcmpg instructions behave almost exactly the same as lcmpl except that they operate on floats and doubles. Each of these four instructions pops the top two values from the stack. If they’re not equal and the first value popped is greater than the second value popped, then -1 is pushed onto the stack. Finally, if the second value popped is greater than the first value popped, 1 is pushed onto the stack. However, they differ in what they do with NaN values. Recall that NaN is unordered. Any comparison with NaN must return false. If either value popped is NaN, then fcmpg and dcmpg push 1 onto the stack, and fcmpl and dcmpl push -1 onto the stack. These two variations are needed to handle NaN comparisons properly.

Reference comparisons

There are four comparison instructions that are used with reference data types. Greater than and less than comparisons make no sense for references, but you can compare references for equality. The if_acmpeq instruction branches if the two references on the top of the stack are equal. The if_acmpne instruction branches if they’re not equal. The ifnull instruction branches if the reference popped from the top of the stack is null. The ifnonnull instruction branches if the reference popped from the top of the stack is not null. All four of these instructions read the next two bytes after the instruction as a signed short giving the relative offset to which they should branch.

Unconditional branching

There are five instructions that branch unconditionally. The instructions goto and goto_w are commonly used to compile while, for, and do-while loops. The instructions jsr, jsr_w, and ret are used to compile finally clauses. The goto and jsr instructions read the next two bytes in the code array as a signed short specifying the location to which it should branch. The goto_w and jsr_w use the next four bytes as a signed int specifying the locations to which they should branch. The jnr, jsr_w, and ret instructions are covered in the section on Exceptions later in this chapter.


Previous Table of Contents Next
HomeAbout UsSearchSubscribeAdvertising InfoContact UsFAQs
Use of this site is subject to certain Terms & Conditions.
Copyright (c) 1996-1999 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.