⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 appa.htm

📁 JAVA Developing Professional JavaApplets
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<BR>&nbsp;&nbsp;&nbsp;&nbsp;u2 attributes_count;<BR>&nbsp;&nbsp;&nbsp;&nbsp;attribute_info attributes[attribute_count];<BR>}</TT></BLOCKQUOTE><P>Code attributes contain a private list of other attributes. Typically,these are debugging lists, such as line number information. Nowthat you've hit the code attribute, it's time to jump into thevirtual machine.<H2><A NAME="TheVirtualMachine"><FONT SIZE=5 COLOR=#FF0000>TheVirtual Machine</FONT></A></H2><P>The Java virtual machine interprets Java byte codes that are containedin code attributes. The virtual machine is stack based. Most computerarchitectures perform their operations on a mixture of memorylocations and registers. The Java virtual machine performs itsoperations exclusively on a stack. This is done primarily to supportportability. No assumptions could be made about the size or numberof registers in a given CPU. Intel microprocessors are especiallylimited in their register composition.<H3><A NAME="Registers">Registers</A></H3><P>The virtual machine does contain some registers, but these areused for tracking the current state of the machine:<UL><LI><TT>pc</TT> register points tothe next bytecode to execute<LI><TT>vars</TT> register pointsto the local variables for a method<LI><TT>optop</TT> register pointsto the operand stack<LI><TT>frame</TT> register pointsto the execution environment</UL><P>All these registers are 32 bits wide and point into separate storageblocks. The blocks, however, can be allocated all at once becausethe code attribute specifies the size of the operand stack, thenumber of local variables, and the length of the bytecodes.<H3><A NAME="OperandStack">Operand Stack</A></H3><P>Most Java byte codes work on the operand stack. For instance,to add two integers together, each integer is pushed onto theoperand stack. The addition operator removes the top two integers,adds them, and places the result in its place back on the stack:<BLOCKQUOTE><TT>..., 4, 5 -&gt; ..., 9<BR></TT></BLOCKQUOTE><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Note</B></TD></TR><TR><TD><BLOCKQUOTE>The operand stack notation is used throughout the remainder of this appendix. The stack reads from left to right, with the stack top on the extreme right. Ellipses indicate indeterminate data buried on the stack. The arrow indicates an operation; the data to the right of the arrow represents the stack after the operation is performed.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>Each stack location is 32 bits wide. Long and doubles are 64 bitswide, so they take up two stack locations.<H2><A NAME="PrimitiveTypes"><FONT SIZE=5 COLOR=#FF0000>PrimitiveTypes</FONT></A></H2><P>The virtual machine provides support for nine primitive types:<UL><LI><TT>byte</TT>-single byte signed2's complement<LI><TT>short</TT>-2-byte signed 2'scomplement<LI><TT>int</TT>-4-byte signed 2'scomplement<LI><TT>long</TT>-8-byte signed 2'scomplement<LI><TT>float</TT>-4-byte IEEE 754single precision<LI><TT>double</TT>-8-byte IEEE 754double precision<LI><TT>char</TT>-2-byte unsignedUnicode character<LI><TT>object</TT>-4-byte referenceto a Java object<LI><TT>returnAddress</TT>-4-bytereference</UL><P>The virtual machine specification does not mandate the internalformat of object references. In Sun's implementation, object referencespoint to a Java handle consisting of two pointers. One pointsto the method table for the class and the other points to theobject's instance data.<H2><A NAME="LocalVariables"><FONT SIZE=5 COLOR=#FF0000>LocalVariables</FONT></A></H2><P>Each code attribute specifies the size of the local variables.A local variable is 32 bits wide, so long and double primitivestake up two variable slots. Unlike C, all method arguments appearas local variables. The operand stack is reserved exclusivelyfor operations.<H3><A NAME="TheVerifier">The Verifier</A></H3><P>When a class is loaded, it is passed through a bytecode verifierbefore it is executed. The verifier checks the internal consistencyof the class and the validity of the code. Java uses a late bindingscheme that puts the code at risk. In traditional languages, theobject linker binds all of the method calls and variable accessesto specific addresses. In Java, the virtual machine doesn't performthis service until the last possible moment. As a result, it ispossible for a called class to have changed since the originalclass was compiled. Method names or their arguments may have beenaltered, or the access levels may have been changed. One of theverifier's jobs is to make sure that all external object referencesare correct and allowed.<P>No assumptions can be made about the origin of bytecodes. A hostilecompiler could be used to create executable bytecodes that conformto the class file format, but specify illegal codes.<P>The verifier uses a conservative four-pass verification algorithmto check bytecodes.<H4>Pass 1</H4><BLOCKQUOTE>This pass reads in the class file and ensures that it is valid.The magic number must be present and all the class data must bepresent with no truncation or extra data after the end of theclass. Any recognized attributes must have the correct lengthand the constant pool must not have any unrecognized entries.</BLOCKQUOTE><H4>Pass 2</H4><BLOCKQUOTE>The second pass involves validating class features other thanthe bytecodes. All methods and fields must have a valid name andsignature and every class must have a super class. Signaturesare not actually checked, but they must appear valid. The nextpass is more specific.</BLOCKQUOTE><H4>Pass 3</H4><BLOCKQUOTE>This is the most complex pass because the bytecodes are validated.The bytecodes are analyzed to make sure that they have the correcttype and number of arguments. In addition, a data-flow analysisis performed to determine each path through the method. Each pathmust arrive at a given point with the same stack size and types.Each path must call methods with the proper arguments, and fieldsmust be modified with values of the appropriate type. Class accessesare not checked in this pass. Only the return type of externalfunctions is verified.</BLOCKQUOTE><BLOCKQUOTE>Forcing all paths to arrive with the same stack and registerscan lead the verifier to fail some otherwise legitimate bytecodes.This is a small price to pay for this high level of security.</BLOCKQUOTE><H4>Pass 4</H4><BLOCKQUOTE>This pass loads externally referenced classes and checks thatthe method name and signatures match. It also validates that thecurrent class has access rights to the external class. After completevalidation, each instruction is replaced with a <TT>_quick</TT>alternative. These <TT>_quick</TT>bytecodes indicate that the class has been verified and need notbe checked again.</BLOCKQUOTE><H3><A NAME="ExceptionHandling">Exception Handling</A></H3><P>The <TT>pc</TT> register points tothe next bytecode to execute. Whenever an exception is thrown,the method's exception table is searched for a handler. Each exceptiontable entry has this format:<BLOCKQUOTE><TT>ExceptionItem<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;u2 start_pc;<BR>&nbsp;&nbsp;&nbsp;&nbsp;u2 end_pc;<BR>&nbsp;&nbsp;&nbsp;&nbsp;u2 handler_pc;<BR>&nbsp;&nbsp;&nbsp;&nbsp;u2 catch_type;<BR>}</TT></BLOCKQUOTE><P>If the <TT>pc</TT> register is withinthe proper range and the thrown exception is the proper type,the entry's handler code block is executed. If no handler is found,the exception propagates up to the calling method. The procedurerepeats itself until either a valid handler is found or the programexits.<H3><A NAME="Bytecodes">Bytecodes</A></H3><P>The bytecodes can be divided into 11 major categories:<UL><LI>Pushing constants onto the stack<LI><FONT COLOR=#000000>Moving local variable contents to andfrom the stack</FONT><LI><FONT COLOR=#000000>Managing arrays</FONT><LI><FONT COLOR=#000000>Generic stack instructions (dup, swap,pop &amp; nop)</FONT><LI><FONT COLOR=#000000>Arithmetic and logical instructions</FONT><LI><FONT COLOR=#000000>Conversion instructions</FONT><LI><FONT COLOR=#000000>Control transfer and function return</FONT><LI><FONT COLOR=#000000>Manipulating object fields</FONT><LI><FONT COLOR=#000000>Method invocation</FONT><LI><FONT COLOR=#000000>Miscellaneous operations</FONT><LI><FONT COLOR=#000000>Monitors</FONT></UL><P>Each bytecode has a unique tag and is followed by a fixed numberof additional arguments. Notice that there is no way to work directlywith class fields or local variables. They must be moved to theoperand stack before any operations can be performed on the contents.<P>Generally, there are multiple formats for each individual operation.The addition operation provides a good example. There are actuallyfour forms of addition: <TT>iadd</TT>,<TT>ladd</TT>, <TT>fadd</TT>,and <TT>dadd</TT>. Each type assumesthe top two stack items are of the correct format: integers, longs,floats, or doubles.<H4>Pushing Constants Onto the Stack</H4><P>Java uses the following instructions for moving object data andlocal variables to the operand stack:<H5>Push One-Byte Signed Integer</H5><BLOCKQUOTE><TT>bipush=16 byte1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stack:... -&gt; ..., byte1</TT></BLOCKQUOTE><H5>Push Two-Byte Signed Integer</H5><BLOCKQUOTE><TT>sipush=17 byte1 byte2&nbsp;&nbsp;&nbsp;&nbsp;Stack:... -&gt; ..., word1</TT></BLOCKQUOTE><H5>Push Item From the Constant Pool (8-bit index)</H5><BLOCKQUOTE><TT>ldc1=18 indexbyte1&nbsp;&nbsp;&nbsp;&nbsp;Stack:... -&gt; ..., item</TT></BLOCKQUOTE><H5>Push Item from the Constant Pool (16-bit index)</H5><BLOCKQUOTE><TT>ldc2=19 indexbyte1 indexbyte2&nbsp;&nbsp;&nbsp;Stack:... -&gt; ..., item</TT></BLOCKQUOTE><H5>Push Long or Double from Constant Pool (16-bit index)</H5><BLOCKQUOTE><TT>ldc2w=20 indexbyte1 indexbyte2&nbsp;&nbsp;&nbsp;Stack:... -&gt; ..., word1, word2</TT></BLOCKQUOTE><H5>Push Null Object</H5><BLOCKQUOTE><TT>aconst_null=1&nbsp;&nbsp;&nbsp;&nbsp;Stack:... -&gt; ..., null</TT></BLOCKQUOTE><H5>Push Integer Constant -1</H5><BLOCKQUOTE><TT>iconst_m1=2&nbsp;&nbsp;&nbsp;Stack: ...-&gt; ..., -1</TT></BLOCKQUOTE><H5>Push Integer Constants</H5><BLOCKQUOTE><TT>iconst_0=3&nbsp;&nbsp;&nbsp;Stack: ...-&gt; ..., 0<BR>iconst_1=4&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 1<BR>iconst_2=5&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 2<BR>iconst_3=6&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 3<BR>iconst_4=7&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 4<BR>iconst_5=8&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 5</TT></BLOCKQUOTE><H5>Push Long Constant</H5><BLOCKQUOTE><TT>lconst_0=9&nbsp;&nbsp;&nbsp;Stack: ...-&gt; ..., 0, 0<BR>lconst_1=10&nbsp;&nbsp;Stack: ... -&gt; ..., 0, 1</TT></BLOCKQUOTE><H5>Push Float Constants</H5><BLOCKQUOTE><TT>fconst_0=11&nbsp;&nbsp;&nbsp;Stack: ...-&gt; ..., 0<BR>fconst_1=12&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 1<BR>fconst_2=13&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 2</TT></BLOCKQUOTE><H5>Push Double Constants</H5><BLOCKQUOTE><TT>dconst_0=14&nbsp;&nbsp;&nbsp;Stack: ...-&gt; ..., 0, 0<BR>dconst_1=15&nbsp;&nbsp;&nbsp;Stack: ... -&gt; ..., 0, 1</TT></BLOCKQUOTE><H4>Accessing Local Variables</H4><P>The most commonly referenced local variables are at the firstfour offsets from the <TT>vars</TT>register. Because of this, Java provides single byte instructionsto access these variables for both reading and writing. A two-byteinstruction is needed to reference variables greater than 4 deep.The variable at location zero is the class pointer itself (the<TT>this</TT> pointer).<H5>Load Integer from Local Variable</H5><BLOCKQUOTE><TT>iload=21 vindex&nbsp;&nbsp;Stack: ...-&gt; ..., contents of varaible at vars[vindex]<BR>iload_o=26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents of variable at vars[0]<BR>iload_1=27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents of variable at vars[1]<BR>iload_2=28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents of variable at vars[2]<BR>iload_3=29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents of variable at vars[3]</TT></BLOCKQUOTE><H5>Load Long Integer from Local Variable</H5><BLOCKQUOTE><TT>lload=22 vindex&nbsp;&nbsp;Stack: ..-&gt; ..., word1, word2&nbsp;&nbsp;from vars[vindex] &amp; vars[vindex+1]<BR>lload_0=30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: .. -&gt;..., word1, word2&nbsp;&nbsp;from vars[0] &amp; vars[1]<BR>lload_1=31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: .. -&gt;..., word1, word2&nbsp;&nbsp;from vars[1] &amp; vars[2]<BR>lload_2=32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: .. -&gt;..., word1, word2&nbsp;&nbsp;from vars[2] &amp; vars[3]<BR>lload_3=33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: .. -&gt;..., word1, word2&nbsp;&nbsp;from vars[3] &amp; vars[4]</TT></BLOCKQUOTE><H5>Load Float from Local Variable</H5><BLOCKQUOTE><TT>fload=23 vindex&nbsp;&nbsp;Stack: ...-&gt; ..., contents from vars[vindex]<BR>fload_0=34&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents from vars[0]<BR>fload_1=35&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents from vars[1]<BR>fload_2=36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents from vars[2]<BR>fload_3=37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., contents from vars[3]</TT></BLOCKQUOTE><H5>Load Double from Local Variable</H5><BLOCKQUOTE><TT>dload=24 vindex&nbsp;&nbsp;Stack: ...-&gt; ..., word1, word2&nbsp;&nbsp;from vars[vindex] &amp; vars[vindex+1]<BR>dload_0=38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., word1, word2&nbsp;&nbsp;from vars[0] &amp; vars[1]<BR>dload_1=39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., word1, word2&nbsp;&nbsp;from vars[1] &amp; vars[2]<BR>dload_2=40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Stack: ... -&gt;..., word1, word2&nbsp;&nbsp;from vars[2] &amp; vars[3]<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -