Java虚拟机的指令由操作码和操作数构成,操作码长度为一个字节,因此总数不超过256条。不考虑异常操作下的执行模型
大多数指令都包含操作所对应的数据类型,记录数据类型的字符叫做助记符:i代表对int类型, l代表long, s代表short, b代表byte, c代表char, f代表float, d代表double, a代表reference。
编译器会在编译期或运行期将byte和short类型的数据带符号扩展(Sign-Extend) 为相应的int类型数据, 将boolean和char类型数据零位扩展(Zero-Extend) 为相应的int类型数据。 与之类似, 在处理boolean、 byte、 short和char类型的数组时, 也会转换为使用对应的int类型的字节码指令来处理。 因此, 大多数对于boolean、 byte、 short和char类型数据的操作, 实际上都是使用相应的对int类型作为运算类型(Computational Type) 来进行的。
加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。
将一个局部变量加载到操作栈: iload、 iload_<n>、 lload、 lload_<n>、 fload、 fload_<n>、 dload、dload_<n>、 aload、 aload
将一个数值从操作数栈存储到局部变量表: istore、 istore_<n>、 lstore、 lstore_<n>、 fstore、fstore_<n>、 dstore、 dstore_<n>、 astore、 astore_<n>
将一个常量加载到操作数栈: bipush、 sipush、 ldc、 ldc_w、 ldc2_w、 aconst_null、 iconst_m1、iconst_<i>、 lconst_<l>、 fconst_<f>、 dconst_<d>
扩充局部变量表的访问索引的指令: wide
以尖括号结尾的指令助记符实际上代表了一组指令,某个带有一个操作数的通用指令的特殊形式。例如iload_<n>
, 它代表了iload_0
、 iload_1
、 iload_2
和iload_3
这几条指令,iload_0
的语义与操作数为0时的iload
指令语义完全一致。
算术指令用于对两个操作数栈上的值进行某种特定运算, 并把结果重新存入到操作栈顶。
以下为小范围类型转换到大范围类型,属于宽泛类型转换,转换时无需显式的转换指令
处理窄化类型转换,需要使用转换指令,i2b、 i2c、 i2s、 l2i、 f2i、 f2l、 d2i、 d2l和d2f 。