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 3 of 5
| Opcode |
Operand(s) |
Description |
| isub |
(none) |
pops two ints, subtracts them, and pushes the int result |
| lsub |
(none) |
pops two longs, subtracts them, and pushes the long result |
Integer multiplication of ints and longs is accomplished via the following opcodes. Each opcode causes two values of the same
type to be popped off the stack and multiplied. The result, of the same type as the numbers being multiplied, is pushed back
onto the stack. No exceptions are thrown.
| Opcode |
Operand(s) |
Description |
| imul |
(none) |
pops two ints, multiplies them, and pushes the int result |
| lmul |
(none) |
pops two longs, multiplies them, and pushes the long result |
The opcodes that perform division on ints and longs are shown in the next table. The division opcodes cause the top two values
of the appropriate type to be popped off the stack. The topmost value is divided by the value just beneath the topmost value.
The result is pushed onto the stack. Integer division yields a result that is truncated down to the nearest integer value
between it and zero. Integer division by zero throws a "/ by 0" ArithmeticException.
| Opcode |
Operand(s) |
Description |
| idiv |
(none) |
pops two ints, divides them, and pushes the int result |
| ldiv |
(none) |
pops two longs, divides them, and pushes the long result |
The remainder operation is accomplished via the following opcodes on ints and longs. The following opcodes cause the top two
values to be popped from the stack. The topmost value is divided by the value just beneath it, and the remainder of that division
is pushed back onto the stack. As with the division opcodes, integer remainder by zero throws a "/ by 0" ArithmeticException.
| Opcode |
Operand(s) |
Description |
| irem |
(none) |
pops two ints, divides them, and pushes the int remainder |
| lrem |
(none) |
pops two longs, divides them, and pushes the long remainder |
The following opcodes perform arithmetic negation on ints and longs. The negation opcodes pop the top value from the stack,
negate it, and push the result.
| Opcode |
Operand(s) |
Description |
| ineg |
(none) |
pops an int, negates it, and pushes the result |
| lneg |
(none) |
pops a long, negates it, and pushes the result |
Logical operands
The JVM's logic capabilities operate on ints and longs. These operations treat ints and longs not as signed two's-complement
numbers, necessarily, but more as generic bit patterns. Integer shifting is accomplished via the ishl, ishr, and iushr opcodes.
Java's << operator is implemented by ishl. The >> operator is implemented by ishr, and the >>> operator is implemented by
iushl. The difference between ishr and iushr is that only ishr does sign extension. The following table shows the instructions
that shift ints left and right.
| Opcode |
Operand(s) |
Description |
| ishl |
(none) |
shifts int left |
| ishr |
(none) |
arithmetic shifts int right |
| iushr |
(none) |
logical shifts int right |
The next table shows the instructions that shift longs left and right.
| Opcode |
Operand(s) |
Description |
| lshl |
(none) |
shifts long left |
| lshr |
(none) |
arithmetic shifts long right |
| lushr |
(none) |
logical shifts long right |
The following opcodes perform bitwise logical operations on ints. The opcodes implement Java's &, |, and ^ operators.