《深入理解java虚拟机》读书笔记(四)类文件结构-2

文章详细介绍了Java虚拟机的字节码指令,包括字节码与数据类型的关系,加载和存储指令如何在局部变量表和操作数栈间传输数据,各种运算指令如加减乘除,以及类型转换指令的用途。此外,还讨论了对象创建与访问的相关指令。
摘要由CSDN通过智能技术生成

1.字节码指令简介

Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(操作码)以及跟随其后的零至多个代表此操作所需的参数(操作数)构成。Java虚拟机面向操作数栈,所以大多数指令都不包括操作数,只有一个操作码,指令参数都放在操作数栈中。

1.1 字节码与数据类型

在虚拟机的指令集中,大多数指令都包含其操作所对应的数据类型信息。但由于Java虚拟机的操作码长度只有一字节,指令集对于特定的操作只提供了有限的类型相关指令去支持它,并非每种数据类型和每一种操作都有对应的指令,有一些单独的指令可以在必要的时候用来将一些不支持的类型转换为可被支持的类型。

表1 Java虚拟机指令集所支持的数据类型

从表1看来,大部分指令都没有支持整数类型byte、char和short,甚至没有任何指令支持boolean类型。编译器会在编译期或运行期将byte和short类型的数据带符号扩展为相应的int类型数据。对数组也是类似的处理方式。

1.2 加载和存储指令

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

  • 将一个局部变量加载到操作栈:iload、iload_、lload、lload_、fload、fload_、dload、dload_、aload、aload_
  • 将一个数值从操作数栈存储到局部变量表:istore、istore_
  • 将一个常量加载到操作数栈:bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconst_ml、iconst_、lconst_、fconst_、dconst_
  • 扩充局部变量表的访问索引的指令:wide

1.3 运算指令

算术指令用于对操作数栈上的两个值进行某种特定运算,并把结果重新存入到操作栈顶。大体上运算指令可以分为两种:对整型数据进行运算的指令与对浮点型数据进行运算的指令。对其他类型如byte、short、char和boolean类型的运算应使用操作int类型的指令代替。

  • 加法指令:iadd、ladd、fadd、dadd
  • 减法指令:isub、lsub、fsub、dsub
  • 乘法指令:imul、lmul、fmul、duml
  • 除法指令
  • 求余指令
  • 取反指令
  • 位移指令
  • 按位或指令
  • 按位与指令
  • 按位异或指令
  • 局部变量自增指令
  • 比较指令

1.4 类型转换指令

类型转换指令可以将两种不同的数值类型相互转换,这些转换操作一般用于实现用户代码中的显式类型转换操作,或者用来处理本节开篇所提到的字节码指令集中数据类型相关指令无法与数据类型一一对应的问题。

Java虚拟机直接支持以下数值类型的宽化类型转换:

  • int类型到long、float或者double类型
  • long类型到float、double类型
  • float类型到double类型

处理窄化类型转换时,就必须显式地使用转换指令来完成,包括i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l和d2f。窄化类型转换可能会导致转换结果产生不同的正负号、不同的数量级的情况,可能会导致数值的精度丢失。

1.5对象创建与访问指令

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值