Logic and integer arithmetic
A look at the bytecodes of the Java virtual machine that perform logical and arithmetic operations
By Bill Venners, JavaWorld.com, 11/11/96
Page 4 of 5
| Opcode |
Operand(s) |
Description |
| iand |
(none) |
boolean ands two ints |
| ior |
(none) |
boolean ors two ints |
| ixor |
(none) |
boolean xors two ints |
The next table shows the opcodes that perform bitwise logical operations on longs.
| Opcode |
Operand(s) |
Description |
| land |
(none) |
boolean ands two longs |
| lor |
(none) |
boolean ors two longs |
| lxor |
(none) |
boolean xors two longs |
Logical results: A JVM simulation
The applet below demonstrates a Java virtual machine executing a sequence of bytecodes. The bytecode sequence in the simulation
was generated by
javac for the incrementLogically() method of the class shown below:
class VulcanCounter {
void incrementLogically() {
int spock = 0;
while (true) {
int tempSpock = spock;
for (int i = 0; i < 32; ++i) {
int mask = 0x1 << i;
if ((tempSpock & mask) == 0) {
tempSpock |= mask;
break;
}
else {
tempSpock &= mask;
}
}
spock = tempSpock;
}
}
}
The actual bytecodes generated by javac for incrementLogically() are shown below:
0 iconst_0 // Push int constant 0.
1 istore_0 // Pop to local variable 0: int spock = 0;
2 iconst_0 // Push int constant 0.
3 istore_1 // Pop to local variable 1: int i = 0;
4 goto 33 // Jump unconditionally ()
7 iconst_1 // Push int constant 1.
8 iload_1 // Push local variable 1 (i).
9 ishl // Arithmetic shift left top int (i) by next to top int (1).
10 istore_2 // Pop to local variable 2: int mask = i << 0x1;
11 iload_0 // Push local variable 0 (spock).
12 iload_2 // Push local variable 2 (mask).
13 iand // Bitwise AND top two ints: (spock & mask)
14 ifne 24 // Jump if top of stack is not equal to zero: if ((spock & mask) == 0) {
17 iload_0 // Push local variable 0 (spock).
18 iload_2 // Push local variable 2 (mask).
19 ior // Bitwise OR top two ints (spock | mask)
20 istore_0 // Pop to local variable 0: spock |= mask;
21 goto 2 // Jump unconditionally (to top of while): break;
24 iload_0 // Push local variable 0 (spock).
25 iload_2 // Push local variable 2 (mask).
26 iconst_m1 // Push -1.
27 ixor // Bitwise EXCLUSIVE-OR top two ints: mask
28 iand // Bitwise AND top two ints: spock & (mask)
29 istore_0 // Pop to local variable 2: spock &= mask;
30 iinc 1 1 // Increment local variable 1 by 1: ++i
33 iload_1 // Push local variable 1 (i).
34 bipush 32 // Push integer constant 32.
36 if_icmplt 7 // Jump (to top of for) if next to top integer is less than top
// integer: i < 32
39 goto 2 // Jump unconditionally (to top of while).
The incrementItLogically() method repeatedly increments an int without using the + or ++ operators. Only logical operators
&, |, and are used. An increment is accomplished by searching through the bits of the current int, starting with the lowest
order bit, and turning ones to zeros. As soon as a one is encountered in the current int, it is changed to zero and the search
stops. The resultant int now represents the old int incremented by one. The process is started again on the new int. Each
incremented number is stored in the spock variable. Spock is local variable zero in the compiled bytecodes, so you can watch
local variable zero count 0, 1, 2, 3, and so on.