Arithmetic and Logic

Processors are either register machines or stack machines.

In a register machine a typical instruction must specify the operator, the source registers that hold the operands (the inputs) and the destination register that will hold the result (the output). For example:

add R0, R1, R2    ; R0 = R1 + R2

Or on some machines:

add R0, R1        ; R0 = R0 + R1

In a stack machine the sources and destinations are understood to reside on a stack, and therefore do not need to be specified. Only the operator is needed. For example:

add               ; replace top 2 items on stack by their sum

The JVM is a stack machine. The operands for all of the arithmetic and logic instructions that occur in the body of a method are understood to reside in the operands stack contained in the stack frame created each time the method is invoked.

For example, the sequence of instructions pushes 6 and 7 onto the operands stack, then replaces them by their product, 42:

ldc 6
ldc 7
imul

We can represent this formally as:

ldc 6    ; <6 ...>
ldc 7    ; <7 6 ...>
imul     ; <42 ...>

Actually, there are many multiplication instructions, one for each type of number.

We can specify the semantics of all multiplication instructions as follows:

?mul     ; <a b ...> -> <a * b ...>

Where:

stack = <a b ...>

? = a, d, f, i, l

Arithmetic Instructions

?add  ; <a b ...> -> <a + b ...>

?div  ; <a b ...> -> <b/a ...>

?mul  ; <a b ...> -> <a * b ...>

?rem  ; <a b ...> -> <b%a ...>

?sub  ; <a b ...> -> <b - a ...>

?neg  ; <a ...> -> <-a ...>

Bitwise Instructions

The shift instructions only work for * = i or * = l

*and  ; <a b ...> -> <a & b ...>

*or   ; <a b ...> -> <a | b ...>

*xor  ; <a b ...> -> <a ^ b ...>

*shl  ; <a b ...> -> <a << b ...>

*ushr ; <a b ...> -> <a >> b ...>

Data Conversion Instructions

For example:

i2f   ; <a ...> -> <a' ...> where a' is the floating point representation of the int a

In general:

?2?   ; <a ...> -> <a' ...> where a' is a represeentation of a in another type

For example:

i2b, i2c, i2d, i2f, i2l, i2s

Not all combinations are supported. Some combinations are specified but not supported in certain implementations.

We can always convert to and from int

We can always convert between the big four: int, fload, long, double

A conversion such as b2i is automatic

f2c needs to be done as f2i, i2c

Conversion to sub-word types can loose information.

Converting from a 32-bit quantity to a 64-bit quantity increases the size of the stack.

References

See Appendix B of your text for a complete list of the Jasmin instructions and their byte codes.