字节码文件解析

基础知识

进制

十进制转二进制

方法为:十进制数除2取余法,即十进制数除2,余数为权位上的数,得到的商值继续除2,依此步骤继续向下运算直到商为0为止。
在这里插入图片描述
二进制转十进制

方法为:把二进制数按权展开、相加即得十进制数。
在这里插入图片描述
二进制转八进制

方法为:3位二进制数按权展开相加得到1位八进制数。(注意事项,3位二进制转成八进制是从右到左开始转换,不足时补0)。
在这里插入图片描述
八进制转成二进制

方法为:八进制数通过除2取余法,得到二进制数,对每个八进制为3个二进制,不足时在最左边补零。
在这里插入图片描述
二进制转十六进制

方法为:与二进制转八进制方法近似,八进制是取三合一,十六进制是取四合一。(注意事项,4位二进制转成十六进制是从右到左开始转换,不足时补0)
在这里插入图片描述
十六进制转二进制

方法为:十六进制数通过除2取余法,得到二进制数,对每个十六进制为4个二进制,不足时在最左边补零。
在这里插入图片描述
十进制与八进制与十六进制之间的转换

十进制转八进制或者十六进制有两种方法

第一:间接法—把十进制转成二进制,然后再由二进制转成八进制或者十六进制。这里不再做图片用法解释。

第二:把十进制转八进制或者十六进制按照除8或者16取余,直到商为0为止。
在这里插入图片描述
八进制或者十六进制转成十进制

方法为:把八进制、十六进制数按权展开、相加即得十进制数。
在这里插入图片描述

不同语言能在JVM上运行的本质(.class)

在这里插入图片描述

认识字节码文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

手动解析字节码文件

在这里插入图片描述
魔数(标志):ca fe ba be
次版本号:00 00
主版本号:00 34 ----->52 jdk1.8
常量池个数(真实的常量池个数 = 字节码文件中的常量池个数 - 1,常量池最小的index不是0,是1 ):00 23-----> 35

解析常量池:

1.0a  00 05 00 16
  tag:0a  method
  class_index: 00 05    5
  name_and_type: 00 16  22

2.09 00 17 00 18
  tag:09  fiel
  class_index: 00 17    23
  name_and_type: 00 18  24

3.0a 00 19 00 1a
  tag:0a  method
  class_index: 00 19    25
  name_and_type: 00 1a  26

4.07 00 1b
  tag:07  class
  class_index: 00 1b 27

5.07 00 1c
  tag:07  class
  class_index: 00 1c 28

6.01 00 06 3c
  tag:01  
  length: 00 06 6
  bytes: 1c  28

7.69 6e 69 74
  tag:69  
  length: 6e 69 
  bytes: 74  

8.3e 10 00 03
  tag:3e  
  length: 10 00
  bytes: 03 

9.28 29 56 01
  tag:
  length: 
  bytes:  
.......

accesss_flag:0021 plubic
this_class:00 04
super_class:00 05
接口数量:00 00
成员属性:00 00

field_info{
	u2     access_flags;
	u2     name_index;
	u2     descriptor_index;
	u2     attributes_count;
	attribute_info attributes[attributes_count]
}

 
 

成员方法:00 02

methods_info[
	method_info {
		u2 access_flags; 00 01 access_flags 项的值是用于定义当前方法的访问权限和基本属性的掩码标志
		u2 name_index; 00 09 指向常量池
		u2 descriptor_index; 00 0A 方法描述符 V代表返回值是void 其他跟字段描述符一样
		u2 attributes_count; 00 01 code属性个数
		attribute_info attributes[attributes_count];
		attributes[
			Code_attribute {
					u2 attribute_name_index; 00 0B  指向常量池,表示字符串code
					u4 attribute_length; 00 00 00 2F attribute_length这个意思是下面所有的字节数加起来是这个数;attribute_length 项的值表示当前属性的长度,不包括开始的 6 个字节
					u2 max_stack; 00 01  操作栈数量,是栈帧里面的 在任意时刻,操作数栈都会有一个确定的栈深度,一个 long 或者 double 类型的数据会占用两个单位的栈深度,其他数据类型则会占用一个单位深度
					u2 max_locals; 00 01 max_locals 项的值给出了分配在当前方法引用的局部变量表中的局部变量个数
					u4 code_length; 00 00 00 05  code_length 项给出了当前方法的 code[]数组的字节数
					u1 code[code_length]; 2A  B7 00 01 B1 code[]数组给出了实现当前方法的 Java 虚拟机字节码---方法体或者说是字节码指令
					u2 exception_table_length; 00 00  异常
					{  u2 start_pc;
					u2 end_pc;
					u2 handler_pc;
					u2 catch_type;
					} exception_table[exception_table_length];
					u2 attributes_count; 00 02 表示attributes数组的个数
					attribute_info attributes[attributes_count];
					attributes[
						LineNumberTable_attribute {  为什么我知道是这个属性勒?因为00 0C指向常量池12,而12就是LineNumberTable_attribute。
								u2 attribute_name_index;  00 0C
								u4 attribute_length; 00 00 00 06  attribute_length 给出了当前属性的长度,不包括开始的 6 个字节
								u2 line_number_table_length; 00 01  说明line_number_table数组的个数,而line_number_table里的元素就是下面的这个{}
								line_number_table[line_number_table_length];
								[
									{  
										u2 start_pc;  00 00  code数组的索引
									   u2 line_number;  00 08  line_number 项的值必须与源文件的行数相匹配
									}
								]
							}
						LocalVariableTable_attribute {
								u2 attribute_name_index; 00 0D     指向常量池
								u4 attribute_length; 00 00 00 0c   当前属性的长度,不包括开始的 6 个字节
								u2 local_variable_table_length;	00 01   local_variable_table[]数组的成员个数
								local_variable_table[local_variable_table_length];
								[
									{  
										u2 start_pc; 00 00  start_pc是local_variable_table的下标
										u2 length;  00 05	length两种意思。具体的看书
										u2 name_index; 00 0E 指向常量池,表示一个局部变量的有效的非全限定名
										u2 descriptor_index; 00 0F 字段描述符
										u2 index;  00 00 	index为此局部变量在当前栈帧的局部变量表中的索引
									}
								] 
							}
					
					]
				}
		]	
	}

类属性:

attribute_info {
	u2   attribute_name_index;
	u4   attribute_length;
	u1   info[attribute_length]
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值