字节码指令简介

lllllan ... 2022-3-21 Java
  • JVM
  • 深入理解Java虚拟机
About 3 min

转载声明

  • 《深入理解Java虚拟机》

Java 虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(操作码,Opcode)以及跟随其后的零至多个代表此操作所需的参数(操作数,Operand)构成。

优点:

  1. 放弃了操作数长度对齐,就意味着可以省略掉大量的填充和间隔字符
  2. 用一个字节来代表操作码,也是为了尽可能获得短小精干的编译代码

缺点:

  1. 操作码的长度为一个字节,意味着指令集的操作码总数不能超过256
  2. 由于 Class 文件格式放弃了编译后代码的操作数长度对齐,意味着虚拟机在处理超过一个字节的数据时,不得不在运行时从字节中重建出具体数据的结构

字节码和数据类型

因为Java虚拟机的操作码长度只有一字节,所以包含了数据类型的操作码就为指令集的设计带来了很大的压力:如果每一种与数据类型相关的指令都支持Java虚拟机所有运行时数据类型的话,那么指令的数量恐怕就会超出一字节所能表示的数量范围了。因此,Java虚拟机的指令集对于特定的操作只提供了有限的类型相关指令去支持它,换句话说,指令集将会被故意设计成非完全独立的。

  1. 加载和存储指令

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

  2. 运算指令

    算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新存入到操作栈顶。

  3. 类型转换指令

    类型转换指令可以将两种不同的数值类型相互转换。

    • Java 虚拟机直接支持(即转换时无须显式的转换指令)数值类型的宽化类型转换(即小范围类型转向大范围类型的安全转换)

    • 处理窄化类型转换时就必须显式地使用转换指令来完成

  4. 对象创建与访问指令

    虽然类实例和数组都是对象,但Java虚拟机对类实例和数组的创建与操作使用了不同的字节码指令。对象创建后,就可以通过对象访问指令获取对象实例或者数组实例中的字段或者数组元素

  5. 操作数栈管理指令

    如同操作一个普通数据结构中的堆栈那样,Java虚拟机提供了一些用于直接操作操作数栈的指令

  6. 控制转移指令

    控制转移指令可以让Java虚拟机有条件或无条件地从指定位置指令(而不是控制转移指令)的下一条指令继续执行程序,从概念模型上理解,可以认为控制指令就是在有条件或无条件地修改PC寄存器的值。

  7. 方法调用和返回指令

    方法调用指令与数据类型无关,而方法返回指令是根据返回值的类型区分的

  8. 异常处理指令

    而在Java虚拟机中,处理异常(catch语句)不是由字节码指令来实现的(很久之前曾经使用jsr和 ret指令来实现,现在已经不用了),而是采用异常表来完成

  9. 同步指令

    Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用 管程 (Monitor,更常见的是直接将它称为“锁”)来实现的

Last update: 2022年3月23日 10:35
Contributors: lllllan