Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does bipush work in JVM?

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?

like image 930
Tim Avatar asked May 04 '18 05:05

Tim


People also ask

What are the machine instructions for JVM?

A Java Virtual Machine instruction consists of an opcode specifying the operation to be performed, followed by zero or more operands embodying values to be operated upon. This chapter gives details about the format of each Java Virtual Machine instruction and the operation it performs.

What is LDC in Java?

ByteCode:ldc pushes a one-word constant onto the operand stack. ldc takes a single parameter, , which is the value to push. Most of the bytecodes in JVM can figure out their name by the code description.

Who executes the ByteCode in Java?

Compiler converts the source code or the Java program into the Byte Code(or machine code), and secondly, the Interpreter executes the byte code on the system. The Interpreter can also be called JVM(Java Virtual Machine).

What is ByteCode in Java with example?

Bytecode is the intermediate representation of a Java program, allowing a JVM to translate a program into machine-level assembly instructions. When a Java program is compiled, bytecode is generated in the form of a . class file. This . class file contains non-runnable instructions and relies on a JVM to be interpreted.


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.

like image 58
Antimony Avatar answered Oct 19 '22 20:10

Antimony


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.

like image 20
chrylis -cautiouslyoptimistic- Avatar answered Oct 19 '22 18:10

chrylis -cautiouslyoptimistic-