字节码指令简介
java虚拟机的指令由一个字节长度的,代表某种含义的数字(操作码,Opcode),以及跟在后面的若干参数组成。由于java虚拟机采用基于栈的指令集机构,因此大多数指令都只有操作码,参数则存在于操作数栈中。
字节码指令集只占1个字节,因此不会最多256条(0~255)。class文件编译后不会执行操作数长度对齐,因此在处理超过一个字节的数据时,必须重建出具体的数据结构,比如将1个16位长度的无符号整数使用2个无符号字节存起来。这种操作某种程度上会损失一些性能,但是由于放弃了长度对齐,可以节省大量的填充和符号间隔。
忽略掉异常,Java虚拟机解释器的执行模型大概如下:
1 |
|
1. 加载和存储指令
将局部变量加载到操作数栈:iload、iload_<n>、lload、lload_<n>、fload、fload_<n>、dload、dload_<n>、aload、aload_<n>
均以下省略_n,代表槽
将数值从操作数栈存储到局部变量表:istore、lstore、fstore、dstore、astore
将常量加载到操作数栈:bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconst_m1、iconst、lconst、fconst、dconst
扩充局部变量表的访问索引指令:wide
2. 运算指令
加法: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
3. 类型转换指令
java虚拟机直接支持小范围到大范围的安全转换,比如int -> long、float、double等。
显示转换指令:i2b、i2c、i2s、l2i、f2l、d2i、d2l、d2f
4. 对象创建指令
创建类实例:new
创建数组:newarray、anewarray、multianewarray
访问类字段:getstatic、putstatic
访问实例字段:getfield、putfield
加载数组元素到操作数栈:baload、caload、saload、iaload、laload、faload、daload、aaload
存储操作数栈的值到数组元素中:bastore、castore、sastore、iastore、lastore、fastore、dastore、aastore、
取数组长度:arraylength
检查实例类型:instanceod、checkcast
5. 操作数栈管理指令
弹出操作数栈栈顶1到2个元素:pop、pop2
复制栈顶1或2个元素并重新入栈:dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2
栈顶两个数值互换:swap
6. 控制转移指令
条件分支:ifeg、iflt、ifne、ifgt、ifnull、ifnonnull、if_icmp eq、if_icmp ne、if_icmp lt、if_icmp gt、if_icmp le、if_icmp ge、if_acmp eq、if_acmp ne
符合条件分支:tableswitch、lookupswitch
无条件分支:goto、goto_w、jsr、jsr_w、ret
7. 方法调用和返回指令
- 调用指令
invokevirtual
:实例方法
invokeinterface
:接口方法
invokeinspecial
:构造方法、私有方法、父类方法
invokestatic
:静态方法
invokedynamic
:运行时动态解析出调用点限定符所引用的方法
- 返回指令
ireturn、lreturn、freturn、dreturn、areturn
注意:返回值为boolean、byte、char、short、int时采用ireturn指令
8. 异常指令
显示抛出的异常:athrow
catch中捕获的异常不是字节码指令实现的,而是采用异常表。
9. 同步指令
方法级的同步无需字节码指令控制,它实现在方法调用和返回之中。当调用时会检查方法表结构中的ACC_SYNCHRONIZED权限,如果设置了则会先获取管程(锁),执行完毕释放管程。如果抛出异常且没有处理此异常,管程将会在异常抛到方法边界之外时自动释放。
synchronized语句块指令:monitorenter、monitorexit
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!