深入理解Android:Java虚拟机ART
上QQ阅读APP看书,第一时间看更新

2.6 Java指令码介绍

2.6.1 指令码和助记符

上文介绍了关于Class文件的一些内容,比如常量池、属性、field_info、method_info等。从笔者角度来看,这些内容还只是对源码文件组成结构的一种描述,而这种组成结构是一种静态内容。比如源码中一个类的每一个成员变量和成员函数都会相应在Class文件里存在一个field_info和method_info。JVM解析这个Class文件后无非是在内存里多创建了一个field_info和method_info对象。不过有了这些信息,JVM好像也无法做什么动作,因为这些信息并不能驱使JVM执行我们在源码中编写的函数。

根据前述知识,我们知道Code_attribute中的code数组存储了一个函数源码经过编译后得到的Java字节码。根据Java虚拟机规范,code数组只能包括下面两种类型的信息。

·首先是Java指令码,即指示JVM该做什么动作,比如是进行加操作还是减操作,或者是new一个对象。在JVM规范中,指令码的长度是1个字节。所以JVM规范中定义的Java指令码的个数不会超过255个(255的16进制表示为0xFF)。

·紧接指令码之后的是0个或多个操作数。JVM在执行某条Java指令码的时候,往往还需要其他一些参数。参数可以直接存储在code数组里,也可以存储在操作栈(Operand stack)中。由于不同指令码可能需要不同个数的参数,所以指令码后面的内容可以是参数(如果这条指令码需要参数)也可以是下一条指令(如果这条指令码无需参数)。

根据上文所述内容,图2-12绘制了code数组里指令和参数的组织格式。

图2-12 code数组中指令和参数的组织格式

图2-12可知Java指令码长度为一个字节。指令码后面跟0或多个参数(占N个字节大小,N>=0)。如何支持一条指令码对应多少个参数呢?不用担心,规范里都定义好了。表2-6所示的表格列出了非常简单的几个指令码。表中第一列为指令码的值(采用16进制表示),表的第二列为这些指令码对应的助记符。第三列是该指令对应所需参数的长度。

表2-6 指令码、助记符和参数个数示例