jvm解析六(JVM规范<下>)
程序员文章站
2022-06-07 16:30:46
...
字节码指令
第一:基本数据类型
加载和存储
1,将一个局部变量加载到操作栈的指令格式格式是:[数据类型only int,long,float,double]+load_<操作数>,例如:iload,iload_<n>,lload,lload_<n>….
2,将一个数值从操作数栈存储到局部变量表指令格式:[数据类型only int,long,float,double]+store_<操作数>,例如:istore,istore_<n>,lstore,lstore_<n>..
3,将一个常量加载到操作数栈的指令格式一:[数据格式(only byte,short)]+ipush,例如:bipush,sipush.
格式二:[数据类型only int,long,float,double]+const_<操作数> ,例如:iconst_ml,iconst_<i>…
4,扩展局部变量表的访问索引的指令:wide
运算指令
1,加法指令格式:[数据类型only int,long,float,double]+add, 例如:iadd,ladd,fadd,dadd
2,减法指令格式:[数据类型only int,long,float,double]+sub, 例如:isub,lsub,fsub,dsub
3,乘法指令格式:[数据类型only int,long,float,double]+mul, 例如:imul,lmul,fmul,dmul
4,乘法指令格式:[数据类型only int,long,float,double]+div, 例如:idiv,ldiv,fdiv,ddiv
5,求余指令格式:[数据类型only int,long,float,double]+rem, 例如:irem,lrem,frem,drem
6,取反指令格式:[数据类型only int,long,float,double]+neg, 例如:ineg,lneg,fneg,dneg
7,位移指令格式:ishl,ishr,iushr,lshl,lushr
8,按位或/与指令格式:[数据类型only int,long]+or/and, 例如:ior/iand,lor/land
9,按位异或指令格式:[数据类型only int,long]+xor, 例如:ixor,lxor
10,局部变量自增指令格式:[数据类型only int]+inc 例如:iinc
11,比较指令格式:dcmpg,dcmpl,fcmpg,fcmpl,lcmp
第二:对象
创建类实例指令:new
创建数组的指令:newarray,anewarray,multianewarray
访问字段指令:[ 非static]getfield,putfield,[static]getstatic,putstatic
把数组元素加载到操作数栈中指令格式:[数组中数据类型byte,short,char, int,long,float,double]+astore,例如:bastore,castore,sastore,iastore,fastore,dastore,aastore
取数组长度: arraylength
检查类实例类型指令:instanceof ,checkcast
方法的调用
1,调用对象的实例方法:invokevirtual
2,调用对象的接口方法:invokeinterface
3,调用特殊处理方法(包括实例初始化方法,私有方法和父类方法):invokespecial
4,调用静态方法:invokestatic
方法的返回指令
Ireturn(当返回值为boolean,byte,char,short,int时),lreturn,freturn,dreturn,areturn,return(void)
第三:操作数栈管理指令
包括:popmpop2,dup,dup2,dup_x1,dup_x2,dup2_x1,dup2_x2
第四:控制指令
条件分支指令:ifeq,iflt,ifge,ifle,ifne,ifnull,ifnonnull,if_icmpeq,if_icmpe,if_cimpgt,if_icmple,if_icmpge,if_acmpeq,if_acmpne
复合条件分支指令:tableswitch,lookupswitch
无条件分支指令:goto,goto_w,jsr,jsr_w,ret
Jvm编译
编译格式
<index><opcode>[<operand1><operand2>…][<comment>]
Index: code[]中操作码的索引
Opcode: 操作码
Operand:操作数
Comment:注释
例子 1:
例子2:
Java代码:
第一:基本数据类型
加载和存储
1,将一个局部变量加载到操作栈的指令格式格式是:[数据类型only int,long,float,double]+load_<操作数>,例如:iload,iload_<n>,lload,lload_<n>….
2,将一个数值从操作数栈存储到局部变量表指令格式:[数据类型only int,long,float,double]+store_<操作数>,例如:istore,istore_<n>,lstore,lstore_<n>..
3,将一个常量加载到操作数栈的指令格式一:[数据格式(only byte,short)]+ipush,例如:bipush,sipush.
格式二:[数据类型only int,long,float,double]+const_<操作数> ,例如:iconst_ml,iconst_<i>…
4,扩展局部变量表的访问索引的指令:wide
运算指令
1,加法指令格式:[数据类型only int,long,float,double]+add, 例如:iadd,ladd,fadd,dadd
2,减法指令格式:[数据类型only int,long,float,double]+sub, 例如:isub,lsub,fsub,dsub
3,乘法指令格式:[数据类型only int,long,float,double]+mul, 例如:imul,lmul,fmul,dmul
4,乘法指令格式:[数据类型only int,long,float,double]+div, 例如:idiv,ldiv,fdiv,ddiv
5,求余指令格式:[数据类型only int,long,float,double]+rem, 例如:irem,lrem,frem,drem
6,取反指令格式:[数据类型only int,long,float,double]+neg, 例如:ineg,lneg,fneg,dneg
7,位移指令格式:ishl,ishr,iushr,lshl,lushr
8,按位或/与指令格式:[数据类型only int,long]+or/and, 例如:ior/iand,lor/land
9,按位异或指令格式:[数据类型only int,long]+xor, 例如:ixor,lxor
10,局部变量自增指令格式:[数据类型only int]+inc 例如:iinc
11,比较指令格式:dcmpg,dcmpl,fcmpg,fcmpl,lcmp
第二:对象
创建类实例指令:new
创建数组的指令:newarray,anewarray,multianewarray
访问字段指令:[ 非static]getfield,putfield,[static]getstatic,putstatic
把数组元素加载到操作数栈中指令格式:[数组中数据类型byte,short,char, int,long,float,double]+astore,例如:bastore,castore,sastore,iastore,fastore,dastore,aastore
取数组长度: arraylength
检查类实例类型指令:instanceof ,checkcast
方法的调用
1,调用对象的实例方法:invokevirtual
2,调用对象的接口方法:invokeinterface
3,调用特殊处理方法(包括实例初始化方法,私有方法和父类方法):invokespecial
4,调用静态方法:invokestatic
方法的返回指令
Ireturn(当返回值为boolean,byte,char,short,int时),lreturn,freturn,dreturn,areturn,return(void)
第三:操作数栈管理指令
包括:popmpop2,dup,dup2,dup_x1,dup_x2,dup2_x1,dup2_x2
第四:控制指令
条件分支指令:ifeq,iflt,ifge,ifle,ifne,ifnull,ifnonnull,if_icmpeq,if_icmpe,if_cimpgt,if_icmple,if_icmpge,if_acmpeq,if_acmpne
复合条件分支指令:tableswitch,lookupswitch
无条件分支指令:goto,goto_w,jsr,jsr_w,ret
Jvm编译
编译格式
<index><opcode>[<operand1><operand2>…][<comment>]
Index: code[]中操作码的索引
Opcode: 操作码
Operand:操作数
Comment:注释
例子 1:
10 dc #1 //Push float constant 100.0
例子2:
Java代码:
Void spin(){ Int i; For(i=0;i<100;i++){ ;//loop body is empty } }编译后代码:
Method void spin() 0 iconst_0 // push int constant0 1 istore_1 // store into local variable (i=0) 2 goto 8 // first time through don’t increment 5 iinc 1 1 //Increment local variable 1 by 1(i++) 8 iload_1 //push local variable 9 bipush 100 //push int constant 100 11 if_icmplt 5 // compare and loop if less than z(i<100) 14 return // return void when done