|
|
|
Advertisement
|
All you ever wanted to know about the if opcode
One family of if opcodes performs integer comparisons
against zero. When the JVM encounters one of these
opcodes, it pops one int off the stack and compares it
with zero.
| Opcode | Operand(s) | Description |
|---|---|---|
ifeq |
branchbyte1, branchbyte2 | pop int value, if value == 0, branch to offset |
ifne |
branchbyte1, branchbyte2 | pop int value, if value != 0, branch to offset |
iflt |
branchbyte1, branchbyte2 | pop int value, if value < 0, branch to offset |
ifle |
branchbyte1, branchbyte2 | pop int value, if value <= 0, branch to offset |
ifgt |
branchbyte1, branchbyte2 | pop int value, if value > 0, branch to offset |
ifge |
branchbyte1, branchbyte2 | pop int value, if value >= 0, branch to offset |
Another family of if opcodes pops two integers off the
top of the stack and compares them against one another. The Java
virtual machine branches if the comparison succeeds. Just before these
opcodes are executed, value2 is on the top of the stack; value1 is just
beneath value2.
| Opcode | Operand(s) | Description |
|---|---|---|
if_icmpeq |
branchbyte1, branchbyte2 | pop int value2 and value1, if value1 == value2, branch to offset |
if_icmpne |
branchbyte1, branchbyte2 | pop int value2 and value1, if value1 != value2, branch to offset |
if_icmplt |
branchbyte1, branchbyte2 | pop int value2 and value1, if value1 < value2, branch to offset |
if_icmple |
branchbyte1, branchbyte2 | pop int value2 and value1, if value1 <= value2, branch to offset |
if_icmpgt |
branchbyte1, branchbyte2 | pop int value2 and value1, if value1 > value2, branch to offset |
if_icmpge |
branchbyte1, branchbyte2 | pop int value2 and value1, if value1 >= value2, branch to offset |
The opcodes shown above operate on ints. These opcodes
also are used for comparisons of types short,
byte, and char -- the JVM
always manipulates types smaller than int by first
converting them to ints and then manipulating the
ints.
A third family of opcodes takes care of comparisons of the other
primitive types: long, float, and
double. These opcodes don't cause a branch by themselves.
Instead, they push the int value that represents the
result of the comparison -- 0 for equal to, 1 for greater than, and -1
for less than -- and then use one of the int compare
opcodes introduced above to force the actual branch.
| Opcode | Operand(s) | Description |
|---|---|---|
lcmp |
(none) | pop long value2 and value1, compare, push int result |
fcmpg |
(none) | pop float value2 and value1, compare, push int result |
fcmpl |
(none) | pop float value2 and value1, compare, push int result |
dcmpg |
(none) | pop double value2 and value1, compare, push int result |
dcmpl |
(none) | pop double value2 and value1, compare, push int result |
The two opcodes for float comparisons (fcmpg
and fcmpl) differ only in how they handle NaN ("not
a number"). In the Java virtual machine, comparisons of floating-point numbers
always fail if one of the values being compared is NaN. If neither
value being compared is NaN, both fcmpg and fcmpl
instructions push a 0 if the values are equal, a 1 if the value1 is
greater than value2, and a -1 if value1 is less than value2. But if one
or both of the values is NaN, the fcmpg instruction pushes a
1, whereas the fcmpl instruction pushes a -1. Because both of
these operands are available, any comparison between two
float values can push the same result onto the stack
independent of whether the comparison failed because of a NaN. This is
also true for the two opcodes that compare double values:
dcmpg and dcmpl.
A fourth family of if opcodes pops one object reference off
the top of the stack and compares it with null. If the comparison succeeds,
the JVM branches.
| Opcode | Operand(s) | Description |
|---|---|---|
ifnull |
branchbyte1, branchbyte2 | pop reference value, if value == null, branches to offset |
ifnonnull |
branchbyte1, branchbyte2 | pop reference value, if value != null, branches to offset |
The last family of if opcodes pops two object
references off the stack and compares them with each other. In this
case, there are only two comparisons that make sense:
"equals" and "not equals." If the references are
equal, then they refer to the exact same object on the heap. If not,
they refer to two different objects. As with all the other
if opcodes, if the comparison succeeds, the JVM branches.
| Opcode | Operand(s) | Description |
|---|---|---|
if_acmpeq |
branchbyte1, branchbyte2 | pop reference value2 and value1, if value1 == value2, branch to offset |
if_acmpne |
branchbyte1, branchbyte2 | pop reference value2 and value1, if value1 != value2, branch to offset |
|
Sponsored Links
|