JVM-初识java虚拟机(五)---Class类文件的结构及JVM指令手册

Class类文件

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,中间没有任何分隔符。Class文件的结构只有两种数据类型:无符号数和表。无符号数以u1、u2、u4和u8来代表1个字节、两个字节、四个字节和八个字节的无符号数,可以用来描述数字、索引引用、数值量或者按UTF-8编码的字符串值。表是有多个无符号数或者其他表作为数据项构成的复合数据类型,习惯性以“_info”结尾。

下面是Class文件的结构:

在这里插入图片描述
1.魔数magic(识别标志)与Java版本号

每个Class前四个字节称为魔数,唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件,该魔数为0xCAFEBABE(咖啡宝贝)。
  紧接着魔数的四个字节存储的是Class的版本号,高版本的JDK能向下兼容以前版本的class文件,但不能运行以后版本的CLass文件。

2.常量池constant_pool
  常量池入口放置容量计数值,该计数值是从1而不是从0开始的。
  主要存放两大类常量:字面量和符号引用。字面量接近于Java语言层面的常量概念,如文本字符串,声明为final的常量值等。符号引用是编译原理方面的概念,包括三类常量:类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。常量池的每一项常量都是一个表,JDK1.7总用有14种表,表开始都是一个u1类型的标志位,代表这种常量属于哪种常量类型。这14种表又各有自己的结构。

3.访问标志access_flag
  用于识别类或接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;是否声明为final等。

4.类索引、父类索引与接口索引集合
  这三项数据确定了这个类的继承关系。
  类索引和父类索引用两个u2类型的索引值表示,它们各自指向一个类型为Constant_Class_info的类描述符常量,通过Constant_Class_info类型的常量中的索引值可以找到定义在Constant_Utf8_info类型的常量中的全限定名字符串。下面是类索引查找过程:
  在这里插入图片描述
5.字段表集合
  字段表用来描述接口或类中声明的变量。下面是字段表的格式
在这里插入图片描述
  描述符的作用是用来描述字段的数据类型、方法的参数列表和返回值。基本数据类型以及代表无返回值的void类型都用一个大写字符表示,而对象类型则用字符L加对象的全限定名来表示。对于数组类型,每一维度增加一个“[”前缀来表示,如定义一个java.lang.String[][]类型的二维数组,则被记录为“[[java/lang/String;”,后面的分号是为了隔开连续的多个全限定名。
  用描述符来描述方法时,按照先参数列表后返回值的顺序描述,参数列表按照参数的严格顺序放在一组小括号“()”中。

**例如:**
//描述符为 ([CII[CIII)I
 int indexOf(char[] source, int sourceOffset, int sourceCount,char[] target, int targetOffset, int targetCount, int fromIndex) { ... }


6.方法表集合
  方法表结构与字段表完全相同。
  如果子类没有重写父类的方法,方法表集合就不会出现父类的方法。编译器可能自动添加方法,最典型的是类构造器“”方法和实力构造器“”方法。

7.属性表集合
  在Class文件、字段表、方法表中都可以携带自己的属性表集合,用于描述某些场景专有的信息。

JVM指令手册

命令行方式查看字节码对应的JVM指令

   javap -c   XXX.class(CLass文件所在位置)

指令手册(栈和局部变量操作)

将常量压入栈的指令

  aconst_null 将null对象引用压入栈 
  iconst_m1 将int类型常量-1压入栈  
  iconst_0 将int类型常量0压入栈  
  iconst_1 将int类型常量1压入栈  
  iconst_2 将int类型常量2压入栈 
  iconst_3 将int类型常量3压入栈  
  iconst_4 将int类型常量4压入栈  
  iconst_5 将int类型常量5压入栈 
  lconst_0 将long类型常量0压入栈 
  lconst_1 将long类型常量1压入栈  
  fconst_0 将float类型常量0压入栈
  fconst_1 将float类型常量1压入栈  
  dconst_0 将double类型常量0压入栈  
  dconst_1 将double类型常量1压入栈  
  bipush 将一个8位带符号整数压入栈  
  sipush 将16位带符号整数压入栈  
  ldc 把常量池中的项压入栈  
  ldc_w 把常量池中的项压入栈(使用宽索引)  
  ldc2_w 把常量池中long类型或者double类型的项压入栈(使用宽索引) 

从栈中的局部变量中装载值的指令

  iload 从局部变量中装载int类型值 
  load 从局部变量中装载long类型值 
  fload 从局部变量中装载float类型值  
  dload 从局部变量中装载double类型值 
  aload 从局部变量中装载引用类型值(refernce) 
  iload_0 从局部变量0中装载int类型值 
  iload_1 从局部变量1中装载int类型值  
  iload_2 从局部变量2中装载int类型值  
  iload_3 从局部变量3中装载int类型值  
  lload_0 从局部变量0中装载long类型值 
  lload_1 从局部变量1中装载long类型值 
  lload_2 从局部变量2中装载long类型值  
  lload_3 从局部变量3中装载long类型值  
  fload_0 从局部变量0中装载float类型值 
  fload_1 从局部变量1中装载float类型值 
  dstore_2 将double类型值存入局部变量2  
  dstore_3 将double类型值存入局部变量3  
  astore_0 将引用类型或returnAddress类型值存入局部变量0  
  astore_1 将引用类型或returnAddress类型值存入局部变量1  
  astore_2 将引用类型或returnAddress类型值存入局部变量2  
  astore_3 将引用类型或returnAddress类型值存入局部变量3  
  iastore 将int类型值存入数组中  
  lastore 将long类型值存入数组中  
  fastore 将float类型值存入数组中
  dastore 将double类型值存入数组中  
  aastore 将引用类型值存入数组中 
  bastore 将byte类型或者boolean类型值存入数组中 
  castore 将char类型值存入数组中  
  sastore 将short类型值存入数组中 

wide指令 wide 使用附加字节扩展局部变量索引
通用(无类型),栈操作

 nop 不做任何操作 
 pop 弹出栈顶端一个字长的内容  
 pop2 弹出栈顶端两个字长的内容  
 dup 复制栈顶部一个字长内容  
 dup_x1 复制栈顶部一个字长的内容,然后将复制内容及原来弹出的两个字长的内容压入栈 
 dup_x2 复制栈顶部一个字长的内容,然后将复制内容及原来弹出的三个字长的内容压入栈  
 dup2 复制栈顶部两个字长内容  
 dup2_x1 复制栈顶部两个字长的内容,然后将复制内容及原来弹出的三个字长的内容压入栈  
 dup2_x2 复制栈顶部两个字长的内容,然后将复制内容及原来弹出的四个字长的内容压入栈  

swap 交换栈顶部两个字长内容
类型转换

 i2l 把int类型的数据转化为long类型  
 i2f 把int类型的数据转化为float类型  
 i2d 把int类型的数据转化为double类型  
 l2i 把long类型的数据转化为int类型  
 l2f 把long类型的数据转化为float类型  
 l2d 把long类型的数据转化为double类型 
 f2i 把float类型的数据转化为int类型  
 f2l 把float类型的数据转化为long类型  
 f2d 把float类型的数据转化为double类型  
 d2i 把double类型的数据转化为int类型  
 d2l 把double类型的数据转化为long类型  
 d2f 把double类型的数据转化为float类型 
 i2b 把int类型的数据转化为byte类型  
 i2c 把int类型的数据转化为char类型  
 i2s 把int类型的数据转化为short类型  

整数运算

 iadd 执行int类型的加法  
 ladd 执行long类型的加法  
 isub 执行int类型的减法  
 lsub 执行long类型的减法  
 imul 执行int类型的乘法  
 lmul 执行long类型的乘法  
 idiv 执行int类型的除法  
 ldiv 执行long类型的除法  
 irem 计算int类型除法的余数  
 lrem 计算long类型除法的余数  
 ineg 对一个int类型值进行取反操作  
 lneg 对一个long类型值进行取反操作  
 iinc 把一个常量值加到一个int类型的局部变量上  
逻辑运算

移位操作

 ishl 执行int类型的向左移位操作  
 lshl 执行long类型的向左移位操作 
 ishr 执行int类型的向右移位操作  
 lshr 执行long类型的向右移位操作  
 iushr 执行int类型的向右逻辑移位操作  
 lushr 执行long类型的向右逻辑移位操作  

按位布尔运算

iand 对int类型值进行“逻辑与”操作  
land 对long类型值进行“逻辑与”操作  
ior 对int类型值进行“逻辑或”操作 
lor 对long类型值进行“逻辑或”操作  
ixor 对int类型值进行“逻辑异或”操作  
lxor 对long类型值进行“逻辑异或”操作 

浮点运算

  fadd 执行float类型的加法  
  dadd 执行double类型的加法  
  fsub 执行float类型的减法  
  dsub 执行double类型的减法  
  fmul 执行float类型的乘法  
  dmul 执行double类型的乘法  
  fdiv 执行float类型的除法  
  ddiv 执行double类型的除法  
  frem 计算float类型除法的余数  
  drem 计算double类型除法的余数  
  fneg 将一个float类型的数值取反  
  dneg 将一个double类型的数值取反 
对象和数组

对象操作指令

    new 创建一个新对象  
    checkcast 确定对象为所给定的类型  
    getfield 从对象中获取字段  
    putfield 设置对象中字段的值 
    getstatic 从类中获取静态字段  
    putstatic 设置类中静态字段的值  
    instanceof 判断对象是否为给定的类型  

数组操作指令

    newarray 分配数据成员类型为基本上数据类型的新数组  
    anewarray 分配数据成员类型为引用类型的新数组  
    arraylength 获取数组长度  
    multianewarray 分配新的多维数组  

控制流

条件分支指令

     ifeq 如果等于0,则跳转  
     ifne 如果不等于0,则跳转  
     iflt 如果小于0,则跳转  ifge 如果大于等于0,则跳转  
     ifgt 如果大于0,则跳转  ifle 如果小于等于0,则跳转  
     if_icmpcq 如果两个int值相等,则跳转  
     if_icmpne 如果两个int类型值不相等,则跳转  
     if_icmplt 如果一个int类型值小于另外一个int类型值,则跳转 
     if_icmpge 如果一个int类型值大于或者等于另外一个int类型值,则跳转  
     if_icmpgt 如果一个int类型值大于另外一个int类型值,则跳转  
     if_icmple 如果一个int类型值小于或者等于另外一个int类型值,则跳转  
     ifnull 如果等于null,则跳转  
     ifnonnull 如果不等于null,则跳转 
     if_acmpeq 如果两个对象引用相等,则跳转 
     if_acmpnc 如果两个对象引用不相等,则跳转 

比较指令

    lcmp 比较long类型值  
    fcmpl 比较float类型值(当遇到NaN时,返回-1)  
    fcmpg 比较float类型值(当遇到NaN时,返回1)  
    dcmpl 比较double类型值(当遇到NaN时,返回-1)  
    dcmpg 比较double类型值(当遇到NaN时,返回1)  

无条件转移指令

  goto 无条件跳转  
  goto_w 无条件跳转(宽索引)  

表跳转指令

tableswitch 通过索引访问跳转表,并跳转  
lookupswitch 通过键值匹配访问跳转表,并执行跳转操作  

异常

athrow 抛出异常或错误  

finally子句

jsr 跳转到子例程  
jsr_w 跳转到子例程(宽索引)  
rct 从子例程返回  

方法调用与返回

方法调用指令

 invokcvirtual 运行时按照对象的类来调用实例方法  
 invokespecial 根据编译时类型来调用实例方法  
 invokestatic 调用类(静态)方法  
 invokcinterface 调用接口方法  

方法返回指令

ireturn 从方法中返回int类型的数据  
lreturn 从方法中返回long类型的数据  
freturn 从方法中返回float类型的数据  
dreturn 从方法中返回double类型的数据  
areturn 从方法中返回引用类型的数据  
return 从方法中返回,返回值为void 

线程同步

  montiorenter 进入并获取对象监视器  
  monitorexit 释放并退出对象监视器 
JVM指令助记符

变量到操作数栈:iload,iload_,lload,lload_,fload,fload_,dload,dload_,aload,aload_

操作数栈到变量: istore,istore_,lstore,lstore_,fstore,fstore_,dstore,dstor_,astore,astore_

常数到操作数栈: bipush,sipush,ldc,ldc_w,ldc2_w,aconst_null,iconst_ml,iconst_,lconst_,fconst_,dconst_
加: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,lshr,iushr,lshl,lshr,lushr 按位或:ior,lor 按位与:iand,land 按位异或:ixor,lxor

类型转换:i2l,i2f,i2d,l2f,l2d,f2d(放宽数值转换) i2b,i2c,i2s,l2i,f2i,f2l,d2i,d2l,d2f(缩窄数值转换)

创建类实便:new

创建新数组:newarray,anewarray,multianwarray

访问类的域和类实例域:getfield,putfield,getstatic,putstatic

把数据装载到操作数栈:baload,caload,saload,iaload,laload,faload,daload,aaload

从操作数栈存存储到数组: bastore,castore,sastore,iastore,lastore,fastore,dastore,aastore

获取数组长度:arraylength

检相类实例或数组属性:instanceof,checkcast

操作数栈管理:pop,pop2,dup,dup2,dup_xl,dup2_xl,dup_x2,dup2_x2,swap

有条件转移:ifeq,iflt,ifle,ifne,ifgt,ifge,ifnull,ifnonnull,if_icmpeq,if_icmpene, if_icmplt,if_icmpgt,if_icmple,if_icmpge,if_acmpeq,if_acmpne,lcmp,fcmpl fcmpg,dcmpl,dcmpg

复合条件转移:tableswitch,lookupswitch

无条件转移:goto,goto_w,jsr,jsr_w,ret

调度对象的实便方法:invokevirtual

调用由接口实现的方法:invokeinterface

调用需要特殊处理的实例方法:invokespecial

调用命名类中的静态方法:invokestatic

方法返回:ireturn,lreturn,freturn,dreturn,areturn,return

异常:athrow

finally关键字的实现使用:jsr,jsr_w,ret

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值