Java虚拟机原理-字节码指令集

本文详细介绍了Java虚拟机(JVM)中的字节码指令集,包括指令集的构成、常见指令的作用及分类,如加载与存储指令、运算指令、类型转换指令等。此外还讲解了与数据类型相关的指令及操作数栈指令。

Java虚拟机原理解析系列


1.字节码指令集概述

1.1 什么是字节码指令集

Java文件的执行,是要先经过编译,形成Class文件,然后经过加载=》连接=》初始化=》使用 到最后的卸载。

我们编写的JAVA代码,经过编译后会形成Class文件,这是我们都知道的。那么Class文件中的内容是什么呢?

JVM底层是有一套自己的指令集合的,Class文件中的内容,其实就是把我们编写的程序逻辑,用JVM的指令来翻译一遍,这样在使用阶段,JVM就可以直接执行了。

JVM的这套指令,就是字节码指令集。这种指令包括 操作码和操作数,就类似于我们调用一个API的方法名和方法的入参。

1.2 字节码指令的构成

字节码指令=操作码+操作数。
操作码:代表某种特定含义的操作。
操作数:可以理解为操作码 需要的参数。

2. 数据类型与Java虚拟机

字节码指令集,大多数都包含其操作所对应的数据类型。

比如:iload 指令代表从局部变量表中加载int行的数据到操作数栈中1,而fload代表的是加载float类型的数据。

因此,在与数据类型相关的字节码指令中,都有一种操作记忆符标明这个指令是专门操作哪种数据类型的。比如l代表long、s代表short、b代表byte、c代表char等

3. 字节码指令详解

下面列举一下字节码指令集中常见的一些指令

3.1 加载和存储指令

指令作用:将数据从Java虚拟机栈的栈帧中的局部变量表和操作数栈之间来回传输。
指令列表:

  • 将局部变量加载到操作数栈:iload、lload、fload、dload等
  • 将一个值存储到局部变量表:istore、lstore、fstore等
  • 将常量加载到操作数栈:bipush、sipush、ldc等

访问对象的字段或者数组的元素的指令,也同样会与操作数栈传输数据。

还有以下两种情况需要注意:

  1. 带操作数的指令:
    iload_<n>:我们知道,iload指令是从局部变量表加载变量到操作数栈,那加一个_<n>是啥意思呢?它代表一组指令,即iload_0、iload_1、iload_2,它们是
    带有操作数的指令,它们表面上没有操作数,实际上操作数都是隐含在指令中的,比如iload_0与iload指令且操作数为0的指令是一个意思。
  2. 隐含操作数类型的指令:
    lconst_<i>:代表加载int型的常量到操作数栈。

更多的加载和存储指令见脚注:

3.2 运算指令

指令作用:用于对两个操作数栈上的值进行运算,并把结果重新放入到栈顶。

指令列表:指令分为两种,对整型运算的指令和对浮点型运算的指令。
在这里插入图片描述

3.3类型转换指令

该类指令用于处理JVM数值类型的相互转换。

JVM支持从小范围向大范围的安全转换(无需显示的转换指令):

  1. int类型转到long、float、double
  2. long类型转换到float、double
  3. float转换为 double

窄类型的转换,需要使用字节码指令进行:
i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l 和 d2f。

窄类型的转换存在一些风险:

  1. 导致结果产生不同的正负号。
  2. 不同的数量级。
  3. 导致数值丢失精度。

3.4对象创建与操作

用来创建对象或者数组。

  • 创建对象的命令:new
  • 创建数组的指令:newarray,anewarray,multianewarray
  • 访问类的静态变量:getstatic、putstatic
  • 访问成员变量:getfield、putfield
  • 加载数组元素到操作数栈:baload、caload、saload、iaload、laload、faload、daload、aaload
  • 把操作数栈的值存储到数组元素:bastore、castore、sastore、
    iastore、fastore、dastore、aastore
  • 取数组长度的指令:arraylength

3.5操作数栈指令

直接操作操作数栈

  • 指令包括:pop、pop2、dup、dup2、
    dup_x1、dup2_x1、dup_x2、dup2_x2 和 swap。

3.6控制转移指令

比如我们代码中写的if…else这种,在JVM中也是有字节码指令与之对应的。

  • 条件分支:ifeq、iflt、ifle、ifne、ifgt、ifge、ifnull、ifnonnull等
  • 无条件分支:goto、goto_w、jsr、jsr_w、ret

3.7 方法调用和返回指令

调用指令:

  • 调用对象的实例方法:invokevirtual
  • 调用接口的方法:invokeinterface
  • 构造方法、私有方法、父类方法调用:invokespecial
  • 调用静态方法:invokestatic

返回指令:
ireturn、lreturn、freturn、dreturn 和 areturn

4. 操作码指令大全

在这里插入图片描述


  1. 对于局部变量表和操作数栈不熟悉的话见我的另一篇博客 Java虚拟机原理-运行时数据区 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值