一个指令由操作码(Opcode)和操作数(Operand)组成。在JVM规范中对操作码给出了一个语义清单和操作数的说明,即我们说的指令集。
----------------------------------------------------------------------------------------
指令集可以说在计算机世界中无处不在,而我们一般说的是CPU的指令集。CPU是依靠指令来计算和控制系统的,每款CPU在设计时就规定了一系列与其硬件电路相配合的指令系统。现阶段的主流指令集可分为精简指令集RISC( reduced instruction set computing)和CISC (complex instruction set computing)。涉及到任何特定芯片编程,了解芯片的指令集是必修课程。
----------------------------------------------------------------------------------------
Java指令集可以分为如下8大类:
□堆栈操作(Stack Operations)
□ 算数操作(Arithmetic Operations)
□ 流程控制操作(Control Flow)
□ 导入和存回操作(Load and Store Operations)
□ 属性操作(Field Access)
□ 方法调用(Method Invocation)
□ 新建对象(Object Allocation)
□ 转换和类型检查(Conversion and Type Checking)
其它具体细节内容,请查阅该章提供的参考资料。我下面给一个简单例子帮助大家理解指令:
Java源代码:

编译后方法main的Java字节码(发现JVM的好多指令没有操作数吧?这就是后面提到的基于堆栈的操作约定带来的操作码简化):

在上面的代码中我们看到了类似<java/lang/StringBuilder/<init>(Ljava/lang/String;)V>的信息,它们是在Java字节码中被称为Descriptor的类型表示格式,在后面内容JNI中本地代码调用Java代码中出现的名称,都是来自该约定。具体约定如下:
□ 简单数据类型通过各自对应的符号来表示,B表示byte,C表示char,D表示double,F表示float,I表示int,J表示long,L后面跟类全名称,再加分号;表示引用,S表示short,Z表示boolean,[表示数组;类用反斜杠隔开的全名称,例如java/lang/StringBuilder。例如String[]可以用[java/lang/String;来表示,int[]可以用[I表示,int[][]可以用[[I来表示。
□ 方法用方法名(顺序参数类型)返回值类型表示。例如int[] method(int a,String b)可以表示为method(ILjava/lang/String;)[I。