JVM 指令
指令
由一个字节长度的,代表着某种特定操作含义的数字(操作码)以及跟随其后若干个代表此操作所需参数(操作数)而构成,大多数没有操作数;
操作码的长度为1个字节. 所以指令集的操作码总数不超过256条
指令助记符是为了方便阅读指令而语义化的一些符号
比如00000001
的指令的助记符为iload
;
字节码与数据类型
分类
加载和存储指令
指令助记符中 xxx_<n>
是操作数为n时的xxx
,他们省略掉了显式的操作数,不需要进行去操作数的动作,实际上操作数就隐含在指令中
-
将一个局部变量加载到操作栈 :
iload
iload_<n>
fload
fload_<n>
lload
lload_<n>
dload
dload_<n>
aload
aload_<n>
-
将一个数值从操作数栈存储到局部变量表
istore
istore_n
fstore
fstore_n
lstore
lstore_n
dstore
dstore_n
astore
astore_n
-
将一个常量加载到操作数栈
bipush
sipush
ldc
ldc_w
ldc2_w
aconst_null
iconst_ml
iconst_<i>
lconst_<l>
fconst_<f>
dconst_<d>
-
扩充局部变量表的访问索引的指令
wide
- Demo
如下的代码
int a = 1;
int b = 2;
int c = 1;
int d = 5;
double x = 44.1;
编译之后的指令为:
0: iconst_1 // 加载int类型的1
1: istore_1 // 存储到slot编号为1的局部变量
2: iconst_2 // 加载int类型的2
3: istore_2 // 存储到slot编号为2的局部变量
4: iconst_1
5: istore_3
6: iconst_5 // 加载int类型的5
7: istore 4 //已经没有省略操作数的istore可用,所以用istore 4
9: ldc2_w #9 // double 44.1d 位于常量池
12: dstore 5
14: return
运算指令
-
加法指令
iadd
ladd
fadd
dadd
-
减法指令
isub
lsub
fsub
dsub
-
乘法指令
imul
lmul
fmul
dmul
-
除法指令
idiv
ldiv
fdiv
ddiv
-
求余指令
irem
lrem
frem
drem
-
取反指令
ineg
lneg
fneg
dneg
-
位移指令
ishl
ishr
iushr
lshl
lshr
lushr
-
按位或指令
ior
lor
-
按位与指令
iand land
-
按位异或指令
ixor lxor
-
局部变量自增指令
iinc
-
比较指令
dcmpg
dcmpl
fcmpg
fcmpl
lcmp
- Demo
a = a+b; // iadd
a = a-b; // isub
a = a*b; // imul
a = a/b; // idiv
a = a%b; // irem
a = a|b; // ior
a = a&b; // iand
a = a^b; // ixor
a = a>>>b; //iushr
a = a>>b; //ishr
a = a<<b; //ishl
a++; //iinc
类型装换指令
-
宽化类型转换 无须显式指令 但是编译之后也会出现 一个指令 比如
i2f
-
窄化类型转换 需要显式指令
i2b
i2c
....
对象创建与访问指令
-
创建类实例
new
-
创建数组
newarray
anewarray
multianewarray
-
访问类字段
getfield
putfield
getstatic
putstatic
-
访问数组元素
b/c/s/i/l/f/d/a+aload
-
将一个操作数栈存储到数组元素的指令
b/c/s/i/f/d/a+astore
-
获取数组长度的指令
arraylength
-
检查类实例的指令
instanceof
checjcast
操作数栈管理指令
-
将操作数栈的栈顶一个或两个元素出栈
pop pop2
-
复制栈顶一个或两个数值并将复制或双份的复制值重新压入栈顶
dup dup2 dup_x1 dup2_x2 dup2_x2
-
将栈顶最顶端的两个数值互换
swap
控制转移指令
-
条件分支
ifeq
iflt
ifle
... -
复合条件分支
tableswitch
lookupswitch
-
无条件分支
goto
goto_W
方法调用和返回指令
-
调用对象实例方法
invokevirtual
-
调用接口方法
invokeinterface
-
调用需要特殊处理的实例方法
invokespecial
-
调用静态方法
invokestatic
-
运行时动态解析出调用点限定符所引的方法
invokedynamic
异常处理指令
-
显式抛出异常
athrow
- 运行时异常自动抛出
同步指令
-
持有管程
monitorenter
-
释放管程
monitorexit