Class文件(二)-属性和字节码指令

上一篇介绍了class文件结构的含义https://blog.csdn.net/m0_37312601/article/details/82221996,这篇主要讲attribute_info表中各个属性及Java虚拟机中的一些指令。

java实例以及分析数据依然与上篇相同,这里就不重新贴了。

属性表的Code属性

方法表长度为methods_count = 2,第一个方法是编译器默认为我们添加的无参构造<init>方法。第二个方法是我们自己写的 inc()方法。属性表的Code属性存储着方法内具体代码的字节码指令,在16进制分析工具中我们将第一个构造方法表的Code属性展开如下图:

Code下包含三个指令操作(opcodes_operation): aload_0 , invokespecial... ,Return。现将对应的字节码贴出,字节码对应的指令需要查表得到,表的内容很多,贴不了。

2A:查表对应指令是aload_0,将局部变量表中第0个变量加载到操作栈,类型为引用类型reference。

B70001:0xB7,查表指令是 invokespecial,执行栈顶指向的对象的方法。0x0001指向常量池的索引,是invokespecial的参数,也是告诉虚拟机到底执行哪一个方法,对应<init>()V 构造方法。

B1: 查表为return指令,这里返回void.

结合javap 解释第二个方法inc , 在命令行中输入javap -verbose ..\TestClass。参数大小args_size=1,是默认对象this。

 

其他常见属性简介

  1. Exceptions属性:列出方法方法中可能抛出的受查异常。
  2. LineNumerTable属性:描述Java源码行号与字节码行号之间的对应关系。
  3. LocalVariableTable属性:描述栈帧中局部变量表中的变量与Java源码中定义的变量的关系,可以在javac中分别使用-g:none 或 -g:vars来取消或生成这项信息。
  4. SourceFile属性:记录生成这个Class文件的源码文件名称。
  5. ConstantValue属性:通知虚拟机自动为静态变量赋值,只有类变量才有这个属性。
  6. InnerClasses属性:记录内部类和宿主之间的关联。
  7. Signature属性:任何类,接口,初始化方法或成员的泛型签名如果包含了类型变量(Type Variables)和参数化类型(Parameterized Types).则Signature属性会记录泛型签名信息。由于Java的泛型采用擦除法实现,为了避免类型信息被擦除后导致签名混乱,需要用这个属性记录信息。

字节码指令

java虚拟机的指令由一个字节长度,代表某种特定操作含义的数字以及紧跟其后代表参数的数值构成。

指令包含数据类型

在Java的指令集中,大多数都包含操作数据的类型信息。如 iload 在局部变量表中加载int型数据到操作数栈中,fadd 浮点型数据相加,dreturn 返回double型数据。字符对应类型{ i -int,l-long , s-short , b-byte , c-char , f-float , d-double , a-reference }。

由于操作码的长度为1个字节,所以指令总数不可能超过256个。大部分指令没有包括byte,char,solt和boolean类型。当这些类型进行运算时会使用相应的int类型运算。

加载和存储指令

用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。

  • 将局部变量加载到操作站:iload,lload , fload ,dload,aload。
  • 将一个数值从操作数栈存储到局部变量表:istore,lstore, fstore,dstore,astore.
  • 将常量加载到操作数栈:bipush, sipush,ldc,ldc_w,ldc2_w,aconst_null,iconst_m1,iconst_<i>,iconst_< l / f / d>.
  • 扩充局部变量表的访问索引的指令:wide。

 

运算下指令

  • 加:i/l/f/d +add;减:i/l/f/d+sub ;乘:i/l/f/d+mul;除:i/l/f/d +div;求余:i/l/f/d+rem; 求反:i/l/f/d+neg;
  • 位移:ishl, ishl, iushr, lshl, lshr, lushr.
  • 按位或指令:ior,lor.
  • 按位与指令:iand,land.
  • 按位异或指令:ixor,lxor.
  • 局部变量自增指令:iinc.
  • 比较指令:dcmpg,dcmpl, fcmpg, fcmpl , lcmp。
  • 类型转换指令:i2b(int 转 byte ), i2c , i2s , l2i , f2l , d2i , d2l和d2f。

 

对象创建与访问指令

  • 创建类实列:new.
  • 创建数组的指令:newarray, anewarray, multianewarray
  • 访问类字段和示例字段:getfield,putfield, getstatic , putstatic.

 

操作数栈的指令

  • 数栈的栈顶元素出栈:pop , pop2;
  • 复制栈顶的数并压入栈顶:dup;dup2,dup_x2;
  • 栈顶端数据交换:swap.

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值