![]() |
|||
![]() ![]() |
![]() |
![]()
|
![]() |
The bipush instruction sign-extends the next byte in the code array to an int and pushes it onto the stack. The ireturn instruction in byte 2 then returns that int from the top of the stack. By using the optimizer, youve reduced nine instructions to three, a saving of 66 percent in both time and space. This is one reason why the names of the local variables are not stored in the byte code. By the time an optimizer is through with the code, there may not be any variables left. The OpcodesThere are more than 200 different opcodes in the Java virtual machine. You certainly dont need to memorize all of them. I suggest that you skim over this section to get a feel for how the different classes of opcodes behave. Then return here for reference when you need more details about a particular opcode that youve encountered in a disassembly. NopNop is short for no operation. When the virtual machine encounters a nop instruction, it does nothing and moves to the next instruction. Neither the stack nor the local variable array is affected. Ive never actually seen a nop instruction appear in .java byte code. It is probably a holdover from other architectures in which nop instructions were used to ensure code alignment. Pushing values onto the stackThe instructions in this section push values onto the stack. This usually precedes some other instruction that uses these values as arguments. The const codes The 15 const instructions push frequently occurring constants onto the operand stack. The mnemonics for these instructions all take the form type const _ value where type is one of a, i, l, or f and value is the value pushed onto the stack. Thus, iconst _ 2 pushes the int 2 onto the stack, and fconst _ 1 pushes the float 1.0 onto the stack. iconst_m1 pushes -1 onto the stack, and aconst_null pushes the null reference onto the stack. bipush and sipush The bipush instruction pushes a signed byte constant onto the stack. It operates on the byte in the code array immediately following itself. It sign-extends the byte to an int and pushes it onto the stack. The sipush instruction pushes a signed short constant onto the stack. It takes the short from the two bytes of the code array immediately following itself. As with everything else in Java, these bytes are in Big-Endian order. The instruction sign-extends the short to an int and pushes it onto the stack. The ldc codes The abbreviation ldc stands for load constant. The three ldc codes copy values from the constant pool onto the stack. The ldc instruction interprets the byte that follows it in the code array as an unsigned index into the constant pool. If that entry in the constant pool is a float or an int, then that value is copied onto the stack. However, if that entry in the constant pool is a string (that is, if it is an index to a UTF8 structure), then a new String object is constructed and initialized to the value of the UTF8 structure. Then a reference to this new String object is placed on the stack. The ldc_w instruction is the same, except that it uses a 2-byte unsigned index into the constant pool. The ldc instruction is used when the desired constant is somewhere between index 0 and index 255. Larger indices require the ldc_w instruction. You can think of ldc_w as an abbreviation for load constant wide. The ldc2_w instruction copies an 8-byte long or double value from the constant pool into the top two words of the stack. The two bytes of the code array immediately following the ldc2_w instruction are interpreted as an unsigned short index into the constant pool. Stack manipulationSeveral instructions operate directly on the words on the stack, without concerning themselves with what those words mean. The pop and pop2 The pop instruction removes or pops the top word from the stack and does nothing with it. The word is completely lost. This instruction can be used only when a word length quantity like an int or a reference is on the stack. You cant use it when theres a two-word type like a double or a long on the stack. For those types, you must use the pop2 instruction, which pops two words from the stack and discards them. You can also use the pop2 instruction to remove two words that contain ints or floats or references from the stack. However, the Java virtual machine does not allow this (or any other) instruction to split the two words of a long or a double.
|
![]() |
|