Skip to main content

Bytecode Instructions

Bytecode Definition

A bytecode is a sequence of bytes. We always have one opcode that is followed by zero or more operands. Lets take a look at an example. We have a simple bytecode. We push two bytes onto the stack and add them together.

The code would look like this:

# Stack []
bpush 1
# Stack [1]
bpush 2
# Stack [1, 2]
badd
# Stack [3]

The bytecode would look like this (byte values are written in hexadecimal):

01 01 01 02 10

Lets group the bytes a little bit to make it more readable:

01 01
01 02
10

We start the interpretation at the first byte. It is the opcode bpush. The interpreter knows that the opcode bpush is always followed by a operand. So it reads the next byte and interprets it as the operand. The instruction tells it to push this byte onto the stack. The pointer is now at the third byte. As we are finished with the first instruction by now, the next byte is interpreted as an opcode again.

(The interpreter will do the same for the next instruction, it is bpush again, so it will do basically the same as for the first instruction.)

After the second bpush instruction, the pointer is at the fifth byte. The next byte is the opcode badd. The interpreter knows that the opcode badd is not followed by any operand. The instruction tells it to add the two bytes on top of the stack together and push the result onto the stack. The pointer is incremented again. This code is bad as the pointer is now at the end of the bytecode, but we have no RET instruction. The interpreter will throw an error. But for this example that should be enough.

Keep in mind, that mistakes in the bytecode can lead to undefined behavior. If we have a byte missing, value bytes can be interpreted as opcodes and vice versa. This is a serious problem and leads to many security issues, especially when we can modify operand bytes during runtime. So be careful when you write your own bytecode (or use tools and not write the bytes by hand).

In the following sections we will define the opcodes and operands they are followed by.

Stack and variable manipulation

The stack hereby refers to a stack of 8-bit-values. We can only put an 8-bit-value (further referred to as a byte, not to be with the data type byte) on top of the stack and we can remove the topmost bit from the stack. We will refer to the topmost byte as the top/head of the stack. The stack is a LIFO (last in, first out) data structure. The stack is our main tool to manipulate data. We can use an instruction to push a constant onto the stack, then we push another constant onto the stack. Now we can use an add instruction to add the two constants together. Our stack will no longer contain the two constants, but the result of the addition. This would look like this:

# Stack []
bpush 1
# Stack [1]
bpush 2
# Stack [1, 2]
badd
# Stack [3]

Be aware that the stack is a stack of 8-bit-values. When we push a short on the stack, the short consists of 16 bits, so we will have 2 bytes on our stack now. Here the above example with a short:

# Stack []
spush 1
# Stack [0, 1]
spush 2
# Stack [0, 1, 0, 2]
sadd
# Stack [0, 3]

In this way we could also combine two bytes to a short, or we could use only won spush to push two bytes onto the stack. This example performs the same operation with bytes, but using spush instead of bpush:

# Stack []
spush 0x0102
# Stack [1, 2]
badd
# Stack [3]

Now we will look at the local variable table. The local variable table is a table of 8-bit-values. We can store a byte in the local variable table and we can load a byte from the local variable table. The local variable table is a table of bytes, so we can only store a byte one position. If we wan't to store a 16-bit-value, we have to store it in two indices. So a short occupies two bytes, an int four and so on.

§ 1.1 Pushing constants onto the stack

In the above example we already used some push instructions. Now lets declare them formally.

§ bpush bpush 0x01

A bpush instruction pushes a single byte (or any 8-bit-value) onto the stack. It can also be used for a boolean or ubyte. Syntax: bpush <u1 value>, so we have the byte signing a bpush instruction and then directly after that the byte we want to push onto the stack. Overall instruction length: 2 bytes.

§ spush spush 0x02

A spush instruction pushes a short (or any 16-bit-value) onto the stack. It can also be used for a ushort. Syntax: spush <u2 value>, so we have the byte signing a spush instruction and then directly after that the short we want to push onto the stack. Overall instruction length: 3 bytes.

§ ipush ipush 0x03

An ipush instruction pushes an integer (or any 32-bit-value) onto the stack. It can also be used for a float or uint. Syntax: ipush <u4 value>, so we have the byte signing a ipush instruction and then directly after that the integer we want to push onto the stack. Overall instruction length: 5 bytes.

§ lpush lpush 0x04

A lpush instruction pushes a long (or any 64-bit-value) onto the stack. It can also be used for a double or ulong. Syntax: lpush <u8 value>, so we have the byte signing a lpush instruction and then directly after that the long we want to push onto the stack. Overall instruction length: 9 bytes.

§ 1.2 Loading data from the local variable table

§ bload bload 0x05

A bload instruction loads a byte from the local variable table onto the stack. The index stores the index of the byte in the local variable table. Syntax: bload <u2 index> Overall instruction length: 3 bytes.

§ sload sload 0x06

A sload instruction loads a short from the local variable table onto the stack. The index stores the index of the bottom byte of the short in the local variable table. The short will be loaded onto the stack. Overall instruction length: 3 bytes. Syntax: sload <u2 index> Overall instruction length: 3 bytes.

§ iload iload 0x07

A iload instruction loads an integer from the local variable table onto the stack. The index stores the index of the bottom byte of the integer in the local variable table. The integer will be loaded onto the stack. Syntax: iload <u2 index> Overall instruction length: 3 bytes.

§ lload lload 0x08

A lload instruction loads a long from the local variable table onto the stack. The index stores the index of the bottom byte of the long in the local variable table. The long will be loaded onto the stack. Syntax: lload <u2 index> Overall instruction length: 3 bytes.

§ 1.3 Storing data in the local variable table

§ bstore bstore 0x09

Store a byte from the stack in the local variable table. The index points to the byte in the local variable table. Syntax: bstore <u2 index> - Overall instruction length: 3 bytes.

§ sstore sstore 0x0A

Store a short from the stack in the local variable table. The index points to the bottom byte of the short. The short occupies two bytes (2 indices) in the local variable table. Syntax: sstore <u2 index> Overall instruction length: 3 bytes.

§ istore istore 0x0B

Store an integer from the stack in the local variable table. The index points to the bottom byte of the integer. The integer occupies four bytes (4 indices) in the local variable table. Syntax: istore <u2 index> Overall instruction length: 3 bytes.

§ lstore lstore 0x0C

Syntax: lstore <u2 index> - Store a long from the stack in the local variable table. The index points to the bottom byte of the long. The long occupies eight bytes (8 indices) in the local variable table.

§ 2 Arithmetic operations

§ 2.1 Addition

§ badd badd 0x10

Add the two bytes from the stack and push the result (byte) onto the stack. Syntax: badd Overall instruction length: 1 byte.

§ sadd sadd 0x11

Add the two shorts from the stack and push the result (short) onto the stack. Syntax: sadd Overall instruction length: 1 byte.

§ iadd iadd 0x12

Add two integers from the stack and push the result (integer) onto the stack. Syntax: iadd Overall instruction length: 1 byte.

§ ladd ladd 0x13

Add two longs from the stack and push the result (long) onto the stack. Syntax: ladd Overall instruction length: 1 byte.

§ fadd fadd 0x14

Add two floats from the stack and push the result (float) onto the stack. Syntax: fadd Overall instruction length: 1 byte.

§ dadd dadd 0x15

Add two doubles from the stack and push the result (double) onto the stack. Syntax: dadd Overall instruction length: 1 byte.

§ 2.2 Subtraction

§ bsub bsub 0x16

Subtract two bytes from the stack and push the result (byte) onto the stack. Syntax: bsub Overall instruction length: 1 byte.

§ ssub ssub 0x17

Subtract two shorts from the stack and push the result (short) onto the stack. Syntax: ssub Overall instruction length: 1 byte.

§ isub isub 0x18

Subtract two integers from the stack and push the result (integer) onto the stack. Syntax: isub Overall instruction length: 1 byte.

§ lsub lsub 0x19

Subtract two longs from the stack and push the result (long) onto the stack. Syntax: lsub Overall instruction length: 1 byte.

§ fsub fsub 0x1A

Subtract two floats from the stack and push the result (float) onto the stack. Syntax: fsub Overall instruction length: 1 byte.

§ dsub dsub 0x1B

Subtract two doubles from the stack and push the result (double) onto the stack. Syntax: dsub Overall instruction length: 1 byte.

§ 2.3 Multiplication

Subtract two unsigned bytes from the stack and push the result (unsigned byte) onto the stack. Syntax: ubsub Overall instruction length: 1 byte.

§ ussub ussub 0x1D

Subtract two unsigned shorts from the stack and push the result (unsigned short) onto the stack. Syntax: ussub Overall instruction length: 1 byte.

§ uisub uisub 0x1E

Subtract two unsigned integers from the stack and push the result (unsigned integer) onto the stack. Syntax: uisub Overall instruction length: 1 byte.

§ ulsub ulsub 0x1F

Subtract two unsigned longs from the stack and push the result (unsigned long) onto the stack. Syntax: ulsub Overall instruction length: 1 byte.

§ 2.3 Multiplication

§ bmul bmul 0x20

Multiply two bytes from the stack and push the result (byte) onto the stack. Syntax: bmul Overall instruction length: 1 byte.

§ smul smul 0x21

Multiply two shorts from the stack and push the result (short) onto the stack. Syntax: smul Overall instruction length: 1 byte.

§ imul imul 0x22

Multiply two integers from the stack and push the result (integer) onto the stack. Syntax: imul Overall instruction length: 1 byte.

§ lmul lmul 0x23

Multiply two longs from the stack and push the result (long) onto the stack. Syntax: lmul Overall instruction length: 1 byte.

§ fmul fmul 0x24

Multiply two floats from the stack and push the result (float) onto the stack. Syntax: fmul Overall instruction length: 1 byte.

§ dmul dmul 0x25

Multiply two doubles from the stack and push the result (double) onto the stack. Syntax: dmul Overall instruction length: 1 byte.

§ ubmul ubmul 0x26

Multiply two unsigned bytes from the stack and push the result (unsigned byte) onto the stack. Syntax: ubmul Overall instruction length: 1 byte.

§ usmul usmul 0x27

Multiply two unsigned shorts from the stack and push the result (unsigned short) onto the stack. Syntax: usmul Overall instruction length: 1 byte.

§ uimul uimul 0x28

Multiply two unsigned integers from the stack and push the result (unsigned integer) onto the stack. Syntax: uimul Overall instruction length: 1 byte.

§ ulmul ulmul 0x29

Multiply two unsigned longs from the stack and push the result (unsigned long) onto the stack. Syntax: ulmul Overall instruction length: 1 byte.

§ 2.4 Division

§ bdiv bdiv 0x2A

Divide two bytes from the stack and push the result (byte) onto the stack. Syntax: bdiv Overall instruction length: 1 byte.

§ sdiv sdiv 0x2B

Divide two shorts from the stack and push the result (short) onto the stack. Syntax: sdiv Overall instruction length: 1 byte.

§ idiv idiv 0x2C

Divide two integers from the stack and push the result (integer) onto the stack. Syntax: idiv Overall instruction length: 1 byte.

§ ldiv ldiv 0x2D

Divide two longs from the stack and push the result (long) onto the stack. Syntax: ldiv Overall instruction length: 1 byte.

§ fdiv fdiv 0x2E

Divide two floats from the stack and push the result (float) onto the stack. Syntax: fdiv Overall instruction length: 1 byte.

§ ddiv ddiv 0x2F

Divide two doubles from the stack and push the result (double) onto the stack. Syntax: ddiv Overall instruction length: 1 byte.

§ ubdiv ubdiv 0x30

Divide two unsigned bytes from the stack and push the result (unsigned byte) onto the stack. Syntax: ubdiv Overall instruction length: 1 byte.

§ usdiv usdiv 0x31

Divide two unsigned shorts from the stack and push the result (unsigned short) onto the stack. Syntax: usdiv Overall instruction length: 1 byte.

§ uidiv uidiv 0x32

Divide two unsigned integers from the stack and push the result (unsigned integer) onto the stack. Syntax: uidiv Overall instruction length: 1 byte.

§ uldiv uldiv 0x33

Divide two unsigned longs from the stack and push the result (unsigned long) onto the stack. Syntax: uldiv Overall instruction length: 1 byte.

§ 2.5 Modulo

§ bmod bmod 0x34

Modulo two bytes from the stack and push the result (byte) onto the stack. Syntax: bmod Overall instruction length: 1 byte.

§ smod smod 0x35

Modulo two shorts from the stack and push the result (short) onto the stack. Syntax: smod Overall instruction length: 1 byte.

§ imod imod 0x36

Modulo two integers from the stack and push the result (integer) onto the stack. Syntax: imod Overall instruction length: 1 byte.

§ lmod lmod 0x37

Modulo two longs from the stack and push the result (long) onto the stack. Syntax: lmod Overall instruction length: 1 byte.

§ fmod fmod 0x38

Modulo two floats from the stack and push the result (float) onto the stack. Syntax: fmod Overall instruction length: 1 byte.

§ dmod dmod 0x39

Modulo two doubles from the stack and push the result (double) onto the stack. Syntax: dmod Overall instruction length: 1 byte.

§ ubmod ubmod 0x3A

Modulo two unsigned bytes from the stack and push the result (unsigned byte) onto the stack. Syntax: ubmod Overall instruction length: 1 byte.

§ usmod usmod 0x3B

Modulo two unsigned shorts from the stack and push the result (unsigned short) onto the stack. Syntax: usmod Overall instruction length: 1 byte.

§ uimod uimod 0x3C

Modulo two unsigned integers from the stack and push the result (unsigned integer) onto the stack. Syntax: uimod Overall instruction length: 1 byte.

§ ulmod ulmod 0x3D

Modulo two unsigned longs from the stack and push the result (unsigned long) onto the stack. Syntax: ulmod Overall instruction length: 1 byte.

§ 2.6 Negation

§ bneg bneg 0x3E

Negate a byte from the stack and push the result (byte) onto the stack. Syntax: bneg Overall instruction length: 1 byte.

§ sneg sneg 0x3F

Syntax: sneg - Negate a short from the stack and push the result (short) onto the stack. Syntax: sneg Overall instruction length: 1 byte.

§ ineg ineg 0x40

Negate an integer from the stack and push the result (integer) onto the stack. Syntax: ineg Overall instruction length: 1 byte.

§ lneg lneg 0x41

Negate a long from the stack and push the result (long) onto the stack. Syntax: lneg Overall instruction length: 1 byte.

§ fneg fneg 0x42

Negate a float from the stack and push the result (float) onto the stack. Syntax: fneg Overall instruction length: 1 byte.

§ dneg dneg 0x43

Negate a double from the stack and push the result (double) onto the stack. Syntax: dneg Overall instruction length: 1 byte.

§ 2.7 Increment

§ binc binc 0x44

Increment a byte from the stack and push the result (byte) onto the stack. Syntax: binc Overall instruction length: 1 byte.

§ sinc sinc 0x45

Increment a short from the stack and push the result (short) onto the stack. Syntax: sinc Overall instruction length: 1 byte.

§ iinc iinc 0x46

Increment an integer from the stack and push the result (integer) onto the stack. Syntax: iinc Overall instruction length: 1 byte.

§ linc linc 0x47

Increment a long from the stack and push the result (long) onto the stack. Syntax: linc Overall instruction length: 1 byte.

§ finc finc 0x48

Increment a float from the stack and push the result (float) onto the stack. Syntax: finc Overall instruction length: 1 byte.

§ dinc dinc 0x49

Increment a double from the stack and push the result (double) onto the stack. Syntax: dinc Overall instruction length: 1 byte.

§ 2.8 Decrement

§ bdec bdec 0x4A

Decrement a byte from the stack and push the result (byte) onto the stack. Syntax: bdec Overall instruction length: 1 byte.

§ sdec sdec 0x4B

Decrement a short from the stack and push the result (short) onto the stack. Syntax: sdec Overall instruction length: 1 byte.

§ idec idec 0x4C

Decrement an integer from the stack and push the result (integer) onto the stack. Syntax: idec Overall instruction length: 1 byte.

§ ldec ldec 0x4D

Decrement a long from the stack and push the result (long) onto the stack. Syntax: ldec Overall instruction length: 1 byte.

§ fdec fdec 0x4E

Decrement a float from the stack and push the result (float) onto the stack. Syntax: fdec Overall instruction length: 1 byte.

§ ddec ddec 0x4F

Decrement a double from the stack and push the result (double) onto the stack. Syntax: ddec Overall instruction length: 1 byte.

§ 3 Bitwise Expressions

§ 3.1 Bitwise and

§ band band 0x50

Bitwise and two bytes from the stack and push the result (byte) onto the stack. Can also be used for boolean and ubyte. Syntax: band Overall instruction length: 1 byte.

§ sand sand 0x51

Bitwise and two shorts from the stack and push the result (short) onto the stack. Can also be used for char and ushort. Syntax: sand Overall instruction length: 1 byte.

§ iand iand 0x52

Bitwise and two integers from the stack and push the result (integer) onto the stack. Can also be used for float and uint. Syntax: iand Overall instruction length: 1 byte.

§ land land 0x53

Bitwise and two longs from the stack and push the result (long) onto the stack. Can also be used for double and ulong. Syntax: land Overall instruction length: 1 byte.

§ 3.2 Bitwise or

§ bor bor 0x54

Bitwise or two bytes from the stack and push the result (byte) onto the stack. Can also be used for boolean and ubyte. Syntax: bor Overall instruction length: 1 byte.

§ sor sor 0x55

Bitwise or two shorts from the stack and push the result (short) onto the stack. Can also be used for char and ushort. Syntax: sor Overall instruction length: 1 byte.

§ ior ior 0x56

Bitwise or two integers from the stack and push the result (integer) onto the stack. Can also be used for float and uint. Syntax: ior Overall instruction length: 1 byte.

§ lor lor 0x57

Bitwise or two longs from the stack and push the result (long) onto the stack. Can also be used for double and ulong. Syntax: lor Overall instruction length: 1 byte.

§ 3.3 Bitwise xor

§ bxor bxor 0x58

Bitwise xor two bytes from the stack and push the result (byte) onto the stack. Can also be used for boolean and ubyte. Syntax: bxor Overall instruction length: 1 byte.

§ sxor sxor 0x59

Bitwise xor two shorts from the stack and push the result (short) onto the stack. Can also be used for char and ushort. Syntax: sxor Overall instruction length: 1 byte.

§ ixor ixor 0x5A

Bitwise xor two integers from the stack and push the result (integer) onto the stack. Can also be used for float and uint. Syntax: ixor Overall instruction length: 1 byte.

§ lxor lxor 0x5B

Bitwise xor two longs from the stack and push the result (long) onto the stack. Can also be used for double and ulong. Syntax: lxor Overall instruction length: 1 byte.

§ 3.4 Bitwise not

§ bnot bnot 0x5C

Invert the byte on top of the stack and push the result (byte) onto the stack. Syntax: bnot Overall instruction length: 1 byte.

§ snot snot 0x5D

Invert the short on top of the stack and push the result (short) onto the stack. Syntax: snot Overall instruction length: 1 byte.

§ inot inot 0x5E

Invert the integer on top of the stack and push the result (integer) onto the stack. Syntax: inot Overall instruction length: 1 byte.

§ lnot lnot 0x5F

Invert the long on top of the stack and push the result (long) onto the stack. Syntax: lnot Overall instruction length: 1 byte.

§ 3.5 Bitwise shift left

§ bshl bshl 0x60

Bitwise shift left a byte from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the byte below defines the byte to shift. Can also be used for boolean and ubyte. Syntax: bshl Overall instruction length: 1 byte.

§ sshl sshl 0x61

Bitwise shift left a short from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the short below defines the short to shift. Can also be used for char and ushort. Syntax: sshl Overall instruction length: 1 byte.

§ ishl ishl 0x62

Bitwise shift left an integer from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the integer below defines the integer to shift. Can also be used for float and uint. Syntax: ishl Overall instruction length: 1 byte.

§ lshl lshl 0x63

Bitwise shift left a long from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the long below defines the long to shift. Can also be used for double and ulong. Syntax: lshl Overall instruction length: 1 byte.

§ 3.6 Bitwise shift right

§ bshr bshr 0x64

Bitwise shift right a byte from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the byte below defines the byte to shift. Can also be used for boolean and ubyte. Syntax: bshr Overall instruction length: 1 byte.

§ sshr sshr 0x65

Bitwise shift right a short from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the short below defines the short to shift. Can also be used for char and ushort. Syntax: sshr Overall instruction length: 1 byte.

§ ishr ishr 0x66

Bitwise shift right an integer from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the integer below defines the integer to shift. Can also be used for float and uint. Syntax: ishr Overall instruction length: 1 byte.

§ lshr lshr 0x67

Bitwise shift right a long from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the long below defines the long to shift. Can also be used for double and ulong. Syntax: lshr Overall instruction length: 1 byte.

§ 3.7 Bitwise shift right unsigned

§ bshru bshru 0x68

Bitwise shift right unsigned a byte from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the byte below defines the byte to shift. Can also be used for boolean and ubyte. Syntax: bshru Overall instruction length: 1 byte.

§ sshr sshr 0x69

Bitwise shift right unsigned a short from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the short below defines the short to shift. Can also be used for char and ushort. Syntax: sshr Overall instruction length: 1 byte.

§ ishru ishru 0x6A

Bitwise shift right unsigned an integer from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the integer below defines the integer to shift. Can also be used for float and uint. Syntax: ishru Overall instruction length: 1 byte.

§ lshru lshru 0x6B

Bitwise shift right unsigned a long from the stack and push the result onto the stack. The top byte of the stack defines the number of bits to shift, the long below defines the long to shift. Can also be used for double and ulong. Syntax: lshru Overall instruction length: 1 byte.

§ 4 CMP Expressions

§ 4.1 CMP

§ bcmp bcmp 0x70

Compare two bytes from the stack and push the result onto the stack. If the top byte is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top byte is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top byte is greater than the second
0 0 0 0 0 0 0 1 // 1, the top byte is equal to the second
0 0 0 0 0 0 1 0 // 2, the top byte is smaller than the second

Syntax: bcmp Overall instruction length: 1 byte.

§ scmp scmp 0x71

Compare two shorts from the stack and push the result onto the stack. If the top short is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top short is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top short is greater than the second
0 0 0 0 0 0 0 1 // 1, the top short is equal to the second
0 0 0 0 0 0 1 0 // 2, the top short is smaller than the second

Syntax: scmp Overall instruction length: 1 byte.

§ icmp icmp 0x72

Compare two integers from the stack and push the result onto the stack. If the top integer is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top integer is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top integer is greater than the second
0 0 0 0 0 0 0 1 // 1, the top integer is equal to the second
0 0 0 0 0 0 1 0 // 2, the top integer is smaller than the second

Syntax: icmp Overall instruction length: 1 byte.

§ lcmp lcmp 0x73

Compare two longs from the stack and push the result onto the stack. If the top long is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top long is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top long is greater than the second
0 0 0 0 0 0 0 1 // 1, the top long is equal to the second
0 0 0 0 0 0 1 0 // 2, the top long is smaller than the second

Syntax: lcmp Overall instruction length: 1 byte.

§ fcmp fcmp 0x74

Compare two floats from the stack and push the result onto the stack. If the top float is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top float is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top float is greater than the second
0 0 0 0 0 0 0 1 // 1, the top float is equal to the second
0 0 0 0 0 0 1 0 // 2, the top float is smaller than the second

Syntax: fcmp Overall instruction length: 1 byte.

§ dcmp dcmp 0x75

Compare two doubles from the stack and push the result onto the stack.

If the top double is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top double is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top double is greater than the second
0 0 0 0 0 0 0 1 // 1, the top double is equal to the second
0 0 0 0 0 0 1 0 // 2, the top double is smaller than the second

Syntax: dcmp Overall instruction length: 1 byte.

§ ubcmp ubcmp 0x76

Compare two unsigned bytes from the stack and push the result onto the stack.

If the top unsigned byte is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top unsigned byte is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top unsigned byte is greater than the second
0 0 0 0 0 0 0 1 // 1, the top unsigned byte is equal to the second
0 0 0 0 0 0 1 0 // 2, the top unsigned byte is smaller than the second

Syntax: ubcmp

Overall instruction length: 1 byte.

§ uscmp uscmp 0x77

Compare two unsigned shorts from the stack and push the result onto the stack.

If the top unsigned short is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top unsigned short is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top unsigned short is greater than the second
0 0 0 0 0 0 0 1 // 1, the top unsigned short is equal to the second
0 0 0 0 0 0 1 0 // 2, the top unsigned short is smaller than the second

Syntax: uscmp

Overall instruction length: 1 byte.

§ uicmp uicmp 0x78

Compare two unsigned integers from the stack and push the result onto the stack.

If the top unsigned integer is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top unsigned integer is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top unsigned integer is greater than the second
0 0 0 0 0 0 0 1 // 1, the top unsigned integer is equal to the second
0 0 0 0 0 0 1 0 // 2, the top unsigned integer is smaller than the second

Syntax: uicmp

Overall instruction length: 1 byte.

§ ulcmp ulcmp 0x79

Compare two unsigned longs from the stack and push the result onto the stack.

If the top unsigned long is greater than the second, the result will be -1, if they are equal, the result will be 0 and if the top unsigned long is smaller than the second, the result will be -1. The result will be a byte.

0 0 0 0 0 0 0 0 // 0, the top unsigned long is greater than the second
0 0 0 0 0 0 0 1 // 1, the top unsigned long is equal to the second
0 0 0 0 0 0 1 0 // 2, the top unsigned long is smaller than the second

Syntax: ulcmp

Overall instruction length: 1 byte.

§ 4.2 Comparison to boolean

You can achieve the same result using jumps, but these are shortcuts for that. These are very commonly used combinations, so for performance reasons, these are included as instructions.

These instructions convert cmp results to booleans.

§ clt clt 0x7A

Compare two values from the stack and push the result onto the stack. Uses the result of the compare operator.

Will return 1 (00000001) only if the top value is smaller than the second value. (so if the cmp result is 00000010)

Syntax: clt

Overall instruction length: 1 byte.

§ cle cle 0x7B

Compare two values from the stack and push the result onto the stack. Uses the result of the compare operator.

Will return 1 (00000001) if the top value is smaller than or equal to the second value. (so if the cmp result is 00000010 or 00000001)

Syntax: cle

Overall instruction length: 1 byte.

§ ceq ceq 0x7C

Compare two values from the stack and push the result onto the stack. Uses the result of the compare operator.

Will return 1 (00000001) if the top value is equal to the second value. (so if the cmp result is 00000001)

Syntax: ceq

Overall instruction length: 1 byte.

§ cne cne 0x7D

Compare two values from the stack and push the result onto the stack. Uses the result of the compare operator.

Will return 1 (00000001) if the top value is not equal to the second value. (so if the cmp result is 00000000 or 00000010)

Syntax: cne

Overall instruction length: 1 byte.

§ cge cge 0x7E

Compare two values from the stack and push the result onto the stack. Uses the result of the compare operator.

Will return 1 (00000001) if the top value is greater than or equal to the second value.

(so if the cmp result is 00000000 or 00000001)

Syntax: cge

Overall instruction length: 1 byte.

§ cgt cgt 0x7F

Compare two values from the stack and push the result onto the stack. Uses the result of the compare operator.

Will return 1 (00000001) if the top value is greater than the second value. (so if the cmp result is 00000000)

Syntax: cgt

Overall instruction length: 1 byte.

§ 5 Control flow

§ 5.1 Jumping

§ jmp jmp 0x80

Jump to the instruction at the given address.

Syntax: jmp <u4 address> Overall instruction length: 5 bytes.

§ jz jz 0x81

Jump to the instruction at the given address if the the comparison result is 1 (00000001) (the two values are equal).

Syntax: jz <u4 address>

Overall instruction length: 5 bytes.

§ jnz jnz 0x82

Jump to the instruction at the given address if the the comparison result is not 1 (00000001) (the two values are not equal).

Syntax: jnz <u4 address>

Overall instruction length: 5 bytes.

§ je je 0x83

Jump to the instruction at the given address if the the comparison result is 1 (00000001) (the two compared values are equal).

Syntax: je <u4 address>

Overall instruction length: 5 bytes.

§ jne jne 0x84

Jump to the instruction at the given address if the the comparison result is not 1 (00000001) (the two values are not equal).

Syntax: jne <u4 address>

Overall instruction length: 5 bytes.

§ jg jg 0x85

Jump to the instruction at the given address if the the comparison result is 0 (00000000) (the first value is greater than the second).

This has no actual byte code, it is here for completeness. Use jz instead, as it does the same.

Syntax: jg <u4 address>

Overall instruction length: 5 bytes.

§ jge jge 0x86

Jump to the instruction at the given address if the the comparison result is 0 (00000000) or 1 (00000001) (the first value is greater than or equal to the second).

Syntax: jge <u4 address>

Overall instruction length: 5 bytes.

§ jl jl 0x87

Jump to the instruction at the given address if the the comparison result is 2 (00000010) (the first value is smaller than the second).

Syntax: jl <u4 address>

Overall instruction length: 5 bytes.

§ jle jle 0x88

Jump to the instruction at the given address if the the comparison result is 2 (00000010) or 1 (00000001) (the first value is smaller than or equal to the second).

Syntax: jle <u4 address>

Overall instruction length: 5 bytes.

§ 5.2 Returning

§ ret ret 0x90

Return from the current method.

Syntax: ret

Overall instruction length: 1 byte.

§ bret bret 0x91

Set the return value to a byte and return value (one byte).

This instruction only sets the return value, it does not return from the method.

Can also be used for boolean and ubyte.

Syntax: bret

Overall instruction length: 1 byte.

§ sret sret 0x92

Set the return value to a short and return value (two bytes).

This instruction only sets the return value, it does not return from the method.

Can also be used for char and ushort.

Syntax: sret

Overall instruction length: 1 byte.

§ iret iret 0x93

Set the return value to an integer and return value (four bytes).

This instruction only sets the return value, it does not return from the method.

Can also be used for float and uint.

Syntax: iret

Overall instruction length: 1 byte.

§ lret lret 0x94

Set the return value to a long and return value (eight bytes).

This instruction only sets the return value, it does not return from the method.

Can also be used for double and ulong.

Syntax: lret

§ 6 Misc

§ 6.1 nop

§ nop nop 0xA0

Does nothing.

Syntax: nop

Overall instruction length: 1 byte.

§ 6.2 pop

§ bpop bpop 0xA1

Pop the top byte from the stack.

Syntax: pop

Overall instruction length: 1 byte.

§ spop spop 0xA2

Pop the top two bytes from the stack.

Syntax: spop

Overall instruction length: 1 byte.

§ ipop ipop 0xA3

Pop the top four bytes from the stack.

Syntax: ipop

Overall instruction length: 1 byte.

§ lpop lpop 0xA4

Pop the top eight bytes from the stack.

Syntax: lpop

Overall instruction length: 1 byte.

§ 6.3 dup

§ bdup bdup 0xA5

Duplicate the top byte on the stack.

Could be used to duplicate a byte, boolean or ubyte.

Syntax: bdup

Overall instruction length: 1 byte.

§ sdup sdup 0xA6

Duplicate the top 2-byte element on the stack.

Could be used to duplicate a short, char or ushort.

Syntax: sdup

Overall instruction length: 1 byte.

§ idup idup 0xA7

Duplicate the top 4-byte element on the stack.

Could be used to duplicate an integer, float or uint.

Syntax: idup

Overall instruction length: 1 byte.

§ ldup ldup 0xA8

Duplicate the top 8-byte element on the stack.

Could be used to duplicate a long, double or ulong.

Syntax: ldup

Overall instruction length: 1 byte.

§ 6.4 cast

§ pcast pcast 0xA9

Perform a primitive cast. The following byte defines the type to cast to.

You can split this byte into two 4-bit numbers (0-15). The first 4-bit number defines the type to cast from, the second 4-bit number defines the type to cast to.

This table shows the available types:

Type(Hex)(Decimal)(Binary)
byte0x000000
short0x110001
int0x220010
long0x330011
ubyte0x440100
ushort0x550101
uint0x660110
ulong0x770111
float0x881000
double0x991001

For example, if you want to cast a byte to a short, you would use 0x01 (0b00010001). You can read this like this: We want to cast 0x 0 to 1, so we use 0x01.

Syntax: pcast <u1 type>

Overall instruction length: 2 bytes.

§ 7 Invoking methods

§ invoke_static invoke_static 0xB0

Invoke a method. Target method must be static!

Syntax: invoke <u4 constant>

The constant should be an utf-8 constant, containing a qualified method name.

Overall instruction length: 5 bytes.

§ invoke_virtual invoke_virtual 0xB1

Call a method on an object. Target method must not be static!

Synthax: call <u4 constant>

The constant should be an utf-8 constant, containing a qualified method name.`

Overall instruction length: 5 bytes

The arguments are taken from right to left from the stack (so you can )

8 bytes from the stack will be taken as address. The arguments will be taken first!

§ 8 Field access

§ load_static load_static 0xB2

Load a static field value

Synthax: load_static <u4 constant>

The constant should be an utf-8 constant, containing a qualified field name.`

Overall instruction length: 5 bytes

§ load_virtual load_virtual 0xB3

Load an virtual field value

Synthax: load_virtual <u4 constant>

The constant should be an utf-8 constant, containing a qualified field name.`

Overall instruction length: 5 bytes

8 bytes from the stack will be taken as address.

§ baload baload 0xB4

Load a byte from an array

Synthax: baload

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

Will put the result (1 byte) on top of the stack

§ saload saload 0xB5

Load a short from an array

Synthax: saload

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

Will put the result (2 byte) on top of the stack

§ iaload iaload 0xB6

Load an integer from an array

Synthax: iaload

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

Will put the result (4 byte) on top of the stack

§ laload laload 0xB7

Load a long from an array

Synthax: laload

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

Will put the result (8 byte) on top of the stack

§ store_static store_static 0xB8

Store a static field value

Synthax: call <u4 constant> The constant should be an utf-8 constant, containing a qualified field name.`

Overall instruction length: 5 bytes

§ store_virtual store_virtual 0xB9

Store a static field value

Synthax: call <u4 constant>

The constant should be an utf-8 constant, containing a qualified field name.`

Overall instruction length: 5 bytes

8 bytes from the stack will be taken as address.

§ bastore bastore 0xBA

Store a byte in an array

Synthax: bastore

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

The value (1 byte) is taken from the stack

§ sastore sastore 0xBB

Store a short in an array

Synthax: sastore

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

The value (2 byte) is taken from the stack

§ iastore iastore 0xBC

Store an integer in an array

Synthax: iastore

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

The value (4 byte) is taken from the stack

§ lastore lastore 0xBD

Store a long in an array

Synthax: lastore

Overall instruction length: 1 byte

The index (4 byte) is taken from the stack

The array (8 byte) is taken from the stack

The value (8 byte) is taken from the stack

§ 9 Creating objects and arrays

§ new_obj new_obj 0xC0

Create a new object

Synthax: new_obj <u4 constant>

The constant should be an utf-8 constant, containing a qualified constructor name.

Overall instruction length: 5 bytes

§ new_arr new_arr 0xC1

Create a new array

Synthax: new_arr <u4 constant>

The constant should be an utf-8 constant, containing a qualified type name.

Overall instruction length: 5 bytes

The length (4 byte) is taken from the stack

§ 10 Throwing exceptions

§ throw throw 0xC2

Throw an exception

Synthax: throw

Overall instruction length: 1 byte

The exception (8 byte) is taken from the stack