I understand iload takes in integers -1 to 5, but how can you extend to higher numbers using a bipush instruction? How is the specific integer being stored with the bytecode?
-
Your question is very unclear, whether you're asking about pushing the values of local variables onto the stack when you have more than 4 local variables to choose from (`iload`), or pushing literals with `bipush`. – chrylis -cautiouslyoptimistic- May 04 '18 at 05:33
-
I'm really asking about both. Is iload_1 loading the integer one? – Tim May 04 '18 at 06:00
-
`iload_1` pushes the `int` in local variable #1 (the second one, since it's zero-based) onto the stack. – chrylis -cautiouslyoptimistic- May 04 '18 at 06:26
-
My mistake, I was getting the instructions mixed. When you are using istore, and you are storing more than 4 variables, how does it handle the size? I figured the variable field is a fixed array. – Tim May 04 '18 at 19:54
-
The size of what? – chrylis -cautiouslyoptimistic- May 04 '18 at 23:01
-
The fixed size of the variable field. – Tim May 05 '18 at 01:15
-
What is a "variable field"? – chrylis -cautiouslyoptimistic- May 05 '18 at 13:07
-
Variable field is how Hotspot VM stores local variables within each frame. – Tim May 17 '18 at 00:48
2 Answers
There's several different instructions that can be used to push an integer constant.
The smallest is the iconst_* instructions. These are only a single byte, because the value is encoded in the opcode itself. iconst_1, iconst_2, etc. are different opcodes. iconst_5
for example would be encoded as the byte 08
.
Note: iload
is a completely unrelated instruction used for loading the value of a local variable. You must have been thinking of iconst_*.
Next is bipush
, which can push a constant between -128 and 127. This instruction is two bytes long - the first byte is the opcode, and the second byte is a signed 8 bit integer. You can even use it to push constants in the range -1 to 5, although doing so would take up more space in the classfile than necessary. For example, bipush 5
would be encoded as 10 05
. (0x10 is the opcode for bipush)
Next is sipush
, which is the same except that it stores a 16 bit constant instead of an 8 bit constant, and hence the instruction is three bytes long. The opcode for sipush is 0x11, so sipush 5
would be encoded as the three byte sequence 11 00 05
.
You might wonder how integer constants which don't fit in 16 bits are stored. In this case, the compiler creates entries in a separate section of the classfile called the constant pool, and then uses the ldc
or ldc_w
instruction to refer to the constant pool entry.

- 37,781
- 10
- 100
- 107
-
So how is a bytecode implemented in the interpreter if it's holding an instruction and a value? I thought each bytecode is an int8_t. – Tim May 04 '18 at 05:58
-
@Tim Each *opcode* is one byte. Depending on their definitions, operations can be followed by operands. – chrylis -cautiouslyoptimistic- May 04 '18 at 06:27
-
Since it's one byte, how are there two values, integer and bipush instruction? – Tim May 04 '18 at 07:24
-
I think you're looking for section 2.11 of the JVMS, which deals with instruction representation. In particular, it uses the obvious order: the opcode, immediately followed by operands in order, big-endian (as all Java representations). In the case of bipush
, this would be the byte 0x10 followed by the literal value.

- 75,269
- 21
- 115
- 152