📄 chap10.html
字号:
<I><STRONG><P>Popping to Local Variables</P>
</I></STRONG><H3><P></H3>For each opcode that pushes a local variable onto the stack there exists a corresponding opcode that pops the top of the stack back into the local variable. The mnemonics of the pop opcodes can be formed from the mnemonics of the push opcodes by replacing "load" with "store." The opcodes that pop <FONT FACE="Courier New">int</FONT>s and <FONT FACE="Courier New">float</FONT>s from the top of the operand stack to a local variable are listed in Table 10-10. Each of these opcodes moves one single-word value from the top of the stack to a local variable.</P>
<P>Table 10-10. Popping single-word values into local variables</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">istore</FONT></TD><TD VALIGN="TOP">vindex</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">int</FONT> to local variable position vindex</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">istore</FONT>_0</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">int</FONT> to local variable position zero</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">istore</FONT>_1</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">int</FONT> to local variable position one</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">istore</FONT>_2</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">int</FONT> to local variable position two</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">istore</FONT>_3</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">int</FONT> to local variable position three</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">fstore</FONT></TD><TD VALIGN="TOP">vindex</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">float</FONT> to local variable position vindex</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">fstore</FONT>_0</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">float</FONT> to local variable position zero</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">fstore</FONT>_1</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">float</FONT> to local variable position one</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">fstore</FONT>_2</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">float</FONT> to local variable position two</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">fstore</FONT>_3</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">float</FONT> to local variable position three</TD></TR>
</TABLE>
<P>Table 10-11 shows the instructions that pop values of type <FONT FACE="Courier New">long</FONT> and <FONT FACE="Courier New">double</FONT> into a local variable. These instructions move a dual-word value from the top of the operand stack to a local variable. </P>
<P>Table 10-11. Popping dual-word values into local variables</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">lstore</FONT></TD><TD VALIGN="TOP">vindex</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">long</FONT> to local variable positions vindex and (vindex + 1)</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">lstore</FONT>_0</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">long</FONT> to local variable positions zero and one</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">lstore</FONT>_1</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">long</FONT> to local variable positions one and two</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">lstore</FONT>_2</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">long</FONT> to local variable positions two and three</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">lstore</FONT>_3</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">long</FONT> to local variable positions three and four</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">dstore</FONT></TD><TD VALIGN="TOP">vindex</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">double</FONT> to local variable positions vindex and (vindex + 1)</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">dstore</FONT>_0</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">double</FONT> to local variable positions zero and one</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">dstore</FONT>_1</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">double</FONT> to local variable positions one and two</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">dstore</FONT>_2</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">double</FONT> to local variable positions two and three</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">dstore</FONT>_3</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">double</FONT> to local variable positions three and four</TD></TR>
</TABLE>
<P>The final group of opcodes that pops to local variables are shown in Table 10-12. These opcodes pop an object reference from the top of the operand stack to a local variable. </P>
<P>Table 10-12. Popping object references into local variables</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">astore</FONT></TD><TD VALIGN="TOP">vindex</TD><TD VALIGN="TOP">pops object reference to local variable position vindex</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">astore</FONT>_0</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops object reference to local variable position zero</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">astore</FONT>_1</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops object reference to local variable position one</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">astore</FONT>_2</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops object reference to local variable position two</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">astore</FONT>_3</TD><TD VALIGN="TOP">(none)</TD><TD VALIGN="TOP">pops object reference to local variable position three</TD></TR>
</TABLE>
<H3><EM><P>The wide Instruction</P>
</EM></H3><P>Unsigned 8-bit local variable indexes, such as the one that follows the <CODE>iload</CODE> instruction, limit the number of local variables in a method to 256. A separate instruction, <CODE>wide</CODE>, can extend an 8-bit index by another 8 bits, which raises the local variable limit to 65,536. The <CODE>wide</CODE> opcode modifies other opcodes. <FONT FACE="Courier New">wide</FONT> can precede an instruction, such as <CODE>iload</CODE>, that takes an 8-bit unsigned local variable index. Two bytes that form a 16-bit unsigned index into the local variables follows the <FONT FACE="Courier New">wide</FONT> opcode and the modified opcode.</P>
<P>Table 10-13 lists all but two of the opcodes that can be modified by <FONT FACE="Courier New">wide</FONT>. The other two opcodes, <FONT FACE="Courier New">iinc</FONT> and <FONT FACE="Courier New">ret</FONT>, are described in later chapters. The <FONT FACE="Courier New">iinc</FONT> instruction and its <FONT FACE="Courier New">wide</FONT> variant are described in Chapter 12, "Integer Arithmetic." The <FONT FACE="Courier New">ret</FONT> instruction and its wide variant are described in Chapter 18, "Finally Clauses."</P>
<P>Table 10-13. Popping object references into local variables</P>
<TABLE WIDTH="500">
<TR><TD VALIGN="TOP"><STRONG>Opcode</STRONG></TD><TD VALIGN="TOP"><STRONG>Operand(s)</STRONG></TD><TD VALIGN="TOP"><STRONG>Description</STRONG></TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">iload</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pushes <FONT FACE="Courier New">int</FONT> from local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">lload</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pushes <FONT FACE="Courier New">long</FONT> from local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">fload</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pushes <FONT FACE="Courier New">float</FONT> from local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">dload</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pushes <FONT FACE="Courier New">double</FONT> from local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">aload</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pushes object reference from local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">istore</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">int</FONT> to local variable position vindex</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">lstore</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">long</FONT> to local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">fstore</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">float</FONT> to local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">dstore</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pops <FONT FACE="Courier New">double</FONT> to local variable position index</TD></TR>
<TR><TD VALIGN="TOP"><FONT FACE="Courier New">wide</FONT></TD><TD VALIGN="TOP"><FONT FACE="Courier New">astore</FONT>, indexbyte1, indexbyte2</TD><TD VALIGN="TOP">pops object reference to local variable position index</TD></TR>
</TABLE>
<P>When verifying bytecode sequences that include <FONT FACE="Courier New">wide</FONT> instructions, the opcode modified by <FONT FACE="Courier New">wide</FONT> is seen as an operand to <FONT FACE="Courier New">wide</FONT>. Jump instructions are not allowed to jump directly to an opcode modified by <FONT FACE="Courier New">wide</FONT>. For example, if a bytecode sequence include the instruction:</P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT FACE="Courier New"><P>wide iload 257</P>
</FONT><P><FONT FACE="Courier New">end</FONT></P></PRE>
<P>No other opcode of that method韘 bytecode sequence would be allowed to jump directly to the <FONT FACE="Courier New">iload</FONT> opcode. In this case, the <FONT FACE="Courier New">iload</FONT> opcode must always be executed as an operand to the <FONT FACE="Courier New">wide</FONT> opcode.</P>
<I><STRONG><P>Fibonacci Forever: A Simulation</P>
</I><P></STRONG>The <I>Fibonacci Forever</I> applet, shown in Figure 10-1, demonstrates a Java Virtual Machine executing a sequence of bytecodes that generate the Fibonacci series. The applet is embedded in a web page on the CD-ROM in file <FONT FACE="Courier New">applets/FibonacciForever.html</FONT>. The bytecode sequence in the simulation was generated by the <CODE>javac</CODE> compiler for the <FONT FACE="Courier New">calcSequence</FONT><CODE>()</CODE> method of the class shown below:</P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// On CD-ROM in file stackops/ex1/Fibonacci.java
<P>class Fibonacci {</P>
<P> </P>
<P> static void calcSequence() {</P>
<P> long fiboNum = 1;</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -