B.5 Instructions

An Oolong instruction corresponds to a single bytecode instruction in the class file. Each instruction is written as a single mnemonic. Depending on the instruction, the mnemonic may be followed by one or more arguments to the instruction.

The following table summarizes all of the available Oolong instructions. The rest of the section provides notes on the arguments.

Mnemonic Arguments Description
aaload   Push array element
aastore   Store a in array element
aconst_null   Push null reference
aload n Push local variable n
aload_0   Push local variable 0
aload_1   Push local variable 1
aload_2   Push local variable 2
aload_3   Push local variable 3
anewarray class Create array of class, length a
areturn   Return reference from method
arraylength   Length of array a
astore n Store a in local variable n
astore_0   Store a in local variable 0
astore_1   Store a in local variable 1
astore_2   Store a in local variable 2
astore_3   Store a in local variable 3
athrow   Throw exception
baload   Push array element
bastore   Store a in array element
bipush n Push int between 128 and 127
caload   Push array element
castore   Store a in array element
checkcast class Throw exception if a is not class
d2f   Convert double to float
d2i   Convert double to int
d2l   Convert double to long
dadd   Add doubles (ab+cd)
daload   Push array element
dastore   Store a in array element
dcmpg   Compare doubles
dcmpl   Compare doubles
dconst_0   Push 0 (double)
dconst_1   Push 1 (double)
ddiv   Divide doubles (ab/cd)
dload n Push local variable n
dload_0   Push local variable 0
dload_1   Push local variable 1
dload_2   Push local variable 2
dload_3   Push local variable 3
dmul   Multiply doubles (ab*cd)
dneg   Negate double (-ab)
drem   Remainder doubles (ab%cd)
dreturn   Return double from method
dstore n Store ab in local variable n
dstore_0   Store a in local variable 0
dstore_1   Store a in local variable 1
dstore_2   Store a in local variable 2
dstore_3   Store a in local variable 3
dsub   Subtract doubles (ab-cd)
dup   Duplicate a
dup_x1   Duplicate b
dup_x2   Duplicate c
dup2   Duplicate ab
dup2_x1   Duplicate bc
dup2_x2   Duplicate cd
f2d   Convert float to double
f2i   Convert float to int
f2l   Convert float to long
fadd   Add floats (a+b)
faload   Push array element
fastore   Store a in array element
fcmpg   Compare floats
fcmpl   Compare floats
fconst_0   Push 0 (float)
fconst_1   Push 1 (float)
fconst_2   Push 2 (float)
fdiv   Divide floats (a/b)
fload n Push local variable n
fload_0   Push local variable 0
fload_1   Push local variable 1
fload_2   Push local variable 2
fload_3   Push local variable 3
fmul   Multiply floats (a*b)
fneg   Negate float (-a)
frem   Remainder floats (a%b)
freturn   Return float from method
fstore n Store a in local variable n
fstore_0   Store a in local variable 0
fstore_1   Store a in local variable 1
fstore_2   Store a in local variable 2
fstore_3   Store a in local variable 3
fsub   Subtract floats (a-b)
getfield class/field desc Push object field
getstatic class/field desc Push static field
goto label Branch always
goto_w label Branch always to label
i2b   Convert int to byte
i2c   Convert int to char
i2d   Convert int to double
i2f   Convert int to float
i2l   Convert int to long
i2s   Convert int to short
iadd   Add ints (a+b)
iaload   Push array element
iand   Bitwise and ints (a & b)
iastore   Store a into array element
iconst_0   Push 0 (int)
iconst_1   Push 1 (int)
iconst_2   Push 2 (int)
iconst_3   Push 3 (int)
iconst_4   Push 4 (int)
iconst_5   Push 5 (int)
iconst_m1   Push 1(int)
idiv   Divide ints (a/b)
if_acmpeq label Branch if a == b
if_acmpne label Branch if a != b
if_icmpeq label Branch if a > b
if_icmpge label Branch if a >= b
if_icmpgt label Branch if a > b
if_icmple label Branch if a <= b
if_icmplt label Branch if a < b
if_icmpne label Branch if a != b
ifeq label Branch if a == 0
ifge label Branch if a >= 0
ifgt label Branch if a > 0
ifle label Branch if a <= 0
iflt label Branch if a < 0
ifne label Branch if a != 0
ifnonnull label Branch if a is not null
ifnull label Branch if a is null
iinc n increment Increment local variable
iload n Push local variable n
iload_0   Push local variable 0
iload_1   Push local variable 1
iload_2   Push local variable 2
iload_3   Push local variable 3
imul   Multiply ints (a*b)
ineg   Negate int (-a)
instanceof class Push 1 if a is class, 0 otherwise
invokeinterface class/method desc n Invoke method through interface with n argument words
invokespecial class/method desc Invoke method directly
invokestatic class/method desc Invoke static method
invokevirtual class/method desc Invoke method virtually
ior   Bitwise or ints (a | b)
irem   Remainder ints (a%b)
ireturn   Return int from method
ishl   Shift int left (a << b)
ishr   Shift int right (a >> c)
istore n Store a in local variable n
istore_0   Store a in local variable 0
istore_1   Store a in local variable 1
istore_2   Store a in local variable 2
istore_3   Store a in local variable 3
isub   Subtract ints (a-b)
iushr   Unsigned shift int right (a >>> c)
ixor   Boolean xor ints (a ^ b)
jsr label Branch to label; push return location
jsr_w label Jump to label
l2d   Convert long to double
l2f   Convert long to float
l2i   Convert long to int
ladd   Add longs (ab+cd)
laload   Push array element
land   Boolean and longs (ab & cd)
lastore   Store a in array element
lcmp   Compare longs
lconst_0   Push 0 (long)
lconst_1   Push 1 (long) ldc
ldc_w x Push x (a constant int, float, or String)
ldc2_w x Push x (a constant long or double)
ldiv   Divide longs (ab/cd)
lload n Push local variable n
lload_0   Push local variable 0
lload_1   Push local variable 1
lload_2   Push local variable 2
lload_3   Push local variable 3
lmul   Multiply longs (ab*cd)
lneg   Negate long (-ab)
lookupswitch tag1: label1 tag2: label2 … default: labeln Branch to label1 on tag1, label2 on tag2, …, labeln otherwise
lor   Boolean or longs (ab | cd)
lrem   Remainder longs (ab%cd)
lreturn   Return long from method
lshl   Shift long left (bc << 9)
lshr   Shift long right (bc >> 9)
lstore n Store ab in local variable n
lstore_0   Store a in local variable 0
lstore_1   Store a in local variable 1
lstore_2   Store a in local variable 2
lstore_3   Store a in local variable 3
lsub   Subtract longs (ab-cd)
lushr   Unsigned shift long right (bc >>> a)
lxor   Boolean xor longs (ab ^ cd)
monitorenter   Gain control of monitor of a
monitorexit   Release monitor of a
multianewarray class n Create multidimensional array with first n dimensions initialized to lengths a,b,c…
new class Create new object of class
newarray type Create array of type, length a
nop   Do nothing
pop   Remove a
pop2   Remove ab
putfield class/field desc Store a in object field
putstatic class/field desc Store a in static field
ret n Branch to location in variable n
return   Return from method
saload   Push array element
sastore   Store a in array element
sipush n Push int between 32,768 and 32767
swap   Swap a and b
tableswitch

n label1

label2

default: labeln

Branch to label1 on n, label2 on n+1, …, labeln otherwise
wide instruction arguments Like instruction, except using wider range of values

B.5.1 Instructions with No Arguments

Most instructions require no arguments; the instruction is written with just the mnemonic. For example:

 aload_0          ; Push the reference in variable 0 freturn          ; Return a float value ladd             ; Add two longs monitorenter     ; Acquire the monitor 

B.5.2 Integers

Integer values are specified as in Java. They may be either numerical constants or single-character literals. For example,

 bipush 65        ; Push the int 65 bipush 0x41      ; Ditto bipush 'A'       ; Same 

B.5.3 Labels

A label indicates a particular instruction. When an instruction has a label as its argument, the destination is the next instruction after the label. For example,

 goto label             ; Jump to the nop instruction ;; This code is skipped label:    nop    aload_0    arraylength    ifeq label          ; Jump again to the nop instruction 

The instruction identified by label is the nop instruction.

B.5.4 Classes

Some instructions, such as new, require classes as arguments. These arguments are written as the fully qualified class name, using slashes (/) as the separators between package components. For example,

 new java/lang/String     ; Create a String 

B.5.5 Fields and Methods

The general format of a field access or method invocation instruction is

 mnemonic classname/entity desc 

where classname is the name of the class, entity is the name of the field or method, and descriptor is the field or method descriptor. For example, to access a method:

 invokevirtual java/io/PrintStream/println (Ljava/lang/String;)V 

In this case, classname is java/io/PrintStream, entity is println, and desc is (Ljava/lang/String;)V.

For a field:

 getstatic java/lang/Math/PI D 

Here, classname is java/lang/Math, entity is PI, and desc is D.

B.5.6 invokeinterface

In the case of the invokeinterface instruction, there is an additional argument: the number of stack elements used in the call, including the object itself. This information is redundant, since it can be determined from the descriptor, but it is required by the JVM. For example,

 invokeinterface Interface/method (JJ[Ljava/lang/String;)D 6 

invokes a method through the interface called Interface, which requires three arguments, two longs and an array of Strings. The number in this case is 6: one for the Interface object, two for each of the longs, and one more for the String array. The double returned is not included.

B.5.7 multianewarray

The multianewarray instruction is used to create a multidimensional array, with the first n dimensions initialized.

The first argument of a multianewarray call is the type descriptor of the type that is to be created. It must be an array type; that is, the descriptor must begin with one or more left brackets ([). The second element describes how much of the array should be initialized. For example,

 bipush 30 bipush 90 sipush 1000 multianewarray [[[[[I 3 

creates a five-dimensional array of ints. The first three dimensions are initialized to 30, 90, and 1000 elements. This is equivalent to the Java expression

 new int[30][90][1000][][] 

which is an array 30 elements long. Each element of the array is 90 elements long. Each element of that array is 1000 elements long. Each of those 30 x 90 x 1000 = 2,700,000 elements is initially null, but it can hold a two-dimensional array of ints.

B.5.8 ldc, ldc_w, and ldc2_w

These three instructions are used to push a constant value onto the stack. These values are represented as in Java. In Oolong, ldc and ldc_w generate identical code. The JVM distinguishes between these two instructions depending on which element of the constant pool holds the value of the constant. If the value is 256 or less, the ldc is used; otherwise, ldc_w is used. Since the Oolong assembler manages the constant pool, it decides whether to use an ldc or ldc_w opcode.

The ldc2_w instruction is used for double and long values, that is, values that take up two stack entries. For example,

 ldc "Some string"              ; Push a String ldc 3.14                       ; Push a floating-point constant ldc_w 3.14                     ; The same ldc2_w 3.1415925358979323D     ; Push a double constant 

B.5.9 newarray

The newarray instruction is used to create a single-dimensional array of one of the base types. The argument specifies the basic type to create. It may be specified either as the Java type name (int), the Java type descriptor (I), or the bytecode internal number for the type (10). This table summarizes the possible values; all values in the same row are equivalent.

Java name Descriptor Value
boolean Z 4
char C 5
float F 6
double D 7
byte B 8
short S 9
int I 10
long J 11

For example,

 sipush 10 newarray J     ; Create a ten-element array of longs 

B.5.10 tableswitch

The tableswitch instruction takes a base value, specified as an integer, followed by a set of labels. If the value is equal to the base value, control transfers to the first label. If it is one greater than the base, it goes to the second label, and so on.

The default case is required; it specifies where to go if the value is lower than the base or if it is greater than the number of provided labels allowed. For example,

 tableswitch 'A'     caseA     caseB     caseC     default: invalidLetter caseA:                ; Handle a letter A caseB:                ; Handle a letter B caseC:                ; Handle a letter C invalidLetter:        ; Throw an exception 

B.5.11 lookupswitch

The lookupswitch instruction is much like tableswitch (section B.5.10), except that instead of a single value, explicit combinations of cases and labels are provided. The cases are int constants. As with tableswitch, the default case is required. For example,

 lookupswitch     'A': caseA     'B': caseB     'C': caseC     default: invalidLetter 

This could also be written as

 lookupswitch     65: caseA     66: caseB     67: caseC     default: invalidLetter 

or as

 lookupswitch     0x41: caseA     0x42: caseB     0x43: caseC     default: invalidLetter 


Programming for the Java Virtual Machine
Programming for the Javaв„ў Virtual Machine
ISBN: 0201309726
EAN: 2147483647
Year: 1998
Pages: 158
Authors: Joshua Engel

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net