Here are the Java control instructions:
conditionals
if
if/else
switch
iterations
for
while
do/while
escapes
return
throw
break
continue
System.exit
See Sequence Control in Java for more details.
A Jasmin instruction begins with an optional label:
LABEL: OPERATOR OPERAND(S) ; COMMENT
Labels are simply a convenient way to refer to the labeled instruction's address in the computer's memory.
(Recall in the JVM instructions are contained in methods which are contained in classes which are contained in the class area of the JVM's memory.)
A labeled instruction can be the target of an unconditional or conditional goto instruction:
goto LABEL ; PC = LABEL
Executing a goto instruction simply alters the PC (program counter).
Goto instructions are also called branches or jumps.
Use an unconditional goto to set up a perpetual loop:
Prompt:
; prompt user for command
; execute command
; display result
goto Prompt ; PC = Prompt
A conditional goto first executes a comparison. If the comparison is true, then the PC is altered, otherwise control falls to the subsequent instruction.
Assume a is an int sitting on top of the operand stack.
ifeq LABEL ; <a
... > -> <...> if (a == 0) goto LABEL
ifge LABEL ; <a ... > ->
<...> if (a >= 0) goto LABEL
ifgt LABEL ; <a ... > ->
<...> if (a > 0) goto LABEL
ifle LABEL ; <a ... > ->
<...> if (a <= 0) goto LABEL
iflt LABEL ; <a ... > ->
<...> if (a < 0) goto LABEL
ifne LABEL ; <a ... > ->
<...> if (a != 0) goto LABEL
The result of comparing two ints is not explicitly stored, instead the program jumps to a specified label:
if_icmpeq LABEL ; <a b...>
-> <...> if (a == b) goto LABEL
if_icmpne LABEL ; <a b...> ->
<...> if (a != b) goto LABEL
if_icmplt LABEL ; <a b...> ->
<...> if (b < a) goto LABEL
if_icmpge LABEL ; <a b...> ->
<...> if (b >= a) goto LABEL
if_icmpgt LABEL ; <a b...> ->
<...> if (b > a) goto LABEL
if_icmple LABEL ; <a b...> ->
<...> if (b <= a) goto LABEL
Conditional branches for other types of data require two instructions. The first instruction is a comparison that replaces two items off the stack with 1, 0, or -1 depending on if the second from top element is >, ==, or < the top element. Another way to think about it, the compare instruction is like the subtract instruction:
?sub ; <a b ...> -> <b - a ...>
except instead of the difference, the sign (1 = positive, 0 = 0, -1 = negative) of the difference is pushed onto the stack.
Assume a and b are longs
lcmp ; <a b ...> -> <c ...> where c = 1 if b > a, 0 if b == a, or -1
For floating point numbers (? = f or d) things are more
complicated because either (or both) of the numbers could be
?cmpg ; <a b ...>
-> <c ...> where c = 1 if b > a or b == NaN or a =
?cmpl ; <a b ...>
-> <c ...> where c = 1 if b > a, 0 if b == a, or -1 if b < a or
b = NaN or a =
The following instructions assume a is an address (recall that null = address 0):
ifnonull LABEL ; <a
... > -> <...> if (a != null) goto LABEL
ifnull LABEL ; <a ... > ->
<...> if (a == null) goto LABEL
Recall that a stack frame contains three control variables:
PC = next instruction to be executed
CF = stack frame of the calling method
METH = the current method
The JVM keeps a pointer to the top-most frame on the Java stack (TOP). This is the stack frame of the currently executing method.
The return instruction is used to return the top item on the operand stack to the caller. It also sets TOP to CF.
?return ; <a...> -> <...> && a (and control) is returned to the caller
Here's a typical Java if/else instruction:
if (a > 5) {
u;v;w;
} else {
x;y;z;
}
m; n; k;
Assume a is an int stored in locals[1], here's how the above instruction would be compiled into Jasmin:
iload 1 ; <...> -> <a...>
ldc 5 ;
<a...> -> <5 a ...>
if_icmple ELSE ; <5 a...> ->
<...> if (a <= 5) goto ELSE
u; v; w;
goto NEXT ; PC = NEXT
ELSE:
x; y; z;
NEXT:
m; n; k;
How would this need to be altered if a was a long, float, or double?
First observe that Java's for and do/while and for instructions can be compiled to Java's while instruction (see Iterations in Java).
Therefore we only need to worry about compiling while loops into Jasmin.
For example, consider the Java statement:
while(a > 5) {
u; v; w;
}
m; n; k;
Assume a is an int stored in locals[1], here's how the above instruction would be compiled into Jasmin:
TOP:
iload 1 ;
<...> -> <a...>
ldc 5 ;
<a...> -> <5 a ...>
if_icmple NEXT ; <5 a...> ->
<...> if (a <= 5) goto NEXT
u; v; w;
goto TOP ; PC = TOP
NEXT:
m; n; k;
How would this need to be altered if a was a long, float, or double?