Skip to content

Java虚拟机(JVM)的字节码指令集

Java虚拟机(JVM)的字节码指令集是用于指导虚拟机如何执行Java程序的基础。JVM字节码是编译后的Java源代码,它是平台无关的中间表示,可以在所有支持JVM的平台上运行。JVM字节码由单字节(byte)的操作码(opcode)组成,有些操作码后面可能跟随一个或多个操作数(operands)。

加载和存储指令

  • aload: 加载引用类型的局部变量到栈顶
  • iload: 加载整型局部变量到栈顶
  • fload: 加载浮点类型局部变量到栈顶
  • dload: 加载双精度浮点类型局部变量到栈顶
  • lload: 加载长整型局部变量到栈顶
  • istore: 将栈顶整型数值存入指定局部变量
  • fstore: 将栈顶浮点型数值存入指定局部变量
  • dstore: 将栈顶双精度浮点型数值存入指定局部变量
  • lstore: 将栈顶长整型数值存入指定局部变量
  • astore: 将栈顶引用类型数值存入指定局部变量

算术指令

  • iadd: 将栈顶两个整数相加并将结果压入栈顶
  • ladd: 长整型数值相加
  • fadd: 浮点数值相加
  • dadd: 双精度浮点数值相加
  • isub: 整数相减
  • lsub: 长整型数值相减
  • fsub: 浮点数值相减
  • dsub: 双精度浮点数值相减
  • imul: 整数相乘
  • lmul: 长整型数值相乘

类型转换指令

  • i2l: 将栈顶整数强制转换为长整型数值
  • i2f: 将栈顶整数强制转换为浮点数值
  • i2d: 将栈顶整数强制转换为双精度浮点数值
  • l2i: 将栈顶长整数强制转换为整型数值
  • l2f: 将栈顶长整数强制转换为浮点数值
  • l2d: 将栈顶长整数强制转换为双精度浮点数值

比较指令

  • ifeq: 当栈顶整数值等于0时跳转
  • ifne: 当栈顶整数值不等于0时跳转
  • iflt: 当栈顶整数值小于0时跳转
  • ifge: 当栈顶整数值大于等于0时跳转
  • ifgt: 当栈顶整数值大于0时跳转
  • ifle: 当栈顶整数值小于等于0时跳转
  • lcmp: 比较栈顶两个长整型数值的大小

控制指令

  • goto: 无条件跳转
  • tableswitch: 根据索引选择跳转
  • lookupswitch: 根据给定值跳转
  • ireturn: 从方法中返回整型数值
  • lreturn: 从方法中返回长整型数值
  • freturn: 从方法中返回浮点型数值
  • dreturn: 从方法中返回双精度浮点型数值
  • areturn: 从方法中返回引用类型数值
  • return: 从方法中返回void类型数值

类和对象操作

  • new: 创建一个对象实例。
  • instanceof: 检查对象是否是指定类型的实例。
  • checkcast: 检查对象是否可以被强制转换为指定的类型。
  • getfield: 获取对象的字段值。
  • putfield: 设置对象的字段值。
  • getstatic: 获取类的静态字段值。
  • putstatic: 设置类的静态字段值。

栈操作指令

  • pop: 弹出栈顶元素。
  • pop2: 弹出栈顶的一个(宽度为2的类型)或两个(宽度为1的类型)元素。
  • dup: 复制栈顶元素并压入栈顶。
  • dup2: 复制栈顶的一个(宽度为2的类型)或两个(宽度为1的类型)元素并压入栈顶。
  • swap: 交换栈顶的两个元素。

加载和存储指令

  • iload: 加载整型局部变量到操作数栈。
  • fload: 加载浮点型局部变量到操作数栈。
  • dload: 加载双精度浮点型局部变量到操作数栈。
  • aload: 加载引用类型局部变量到操作数栈。
  • istore: 将栈顶整型数值存入局部变量。
  • fstore: 将栈顶浮点型数值存入局部变量。
  • dstore: 将栈顶双精度浮点型数值存入局部变量。
  • astore: 将栈顶引用类型数值存入局部变量。

算术指令

  • iadd: 整数加法。
  • isub: 整数减法。
  • imul: 整数乘法。
  • idiv: 整数除法。
  • irem: 整数取余。
  • ineg: 整数取反。

逻辑和位操作指令

  • ishl: 整数左移位。
  • ishr: 整数右移位。
  • iushr: 无符号整数右移位。
  • iand: 整数与操作。
  • ior: 整数或操作。
  • ixor: 整数异或操作。

类型转换指令

  • i2l: 整型转为长整型。
  • i2f: 整型转为浮点型。
  • i2d: 整型转为双精度浮点型。
  • l2i: 长整型转为整型。
  • l2f: 长整型转为浮点型。
  • l2d: 长整型转为双精度浮点型。

控制流指令

  • ifeq: 如果等于0,则跳转。
  • ifne: 如果不等于0,则跳转。
  • iflt: 如果小于0,则跳转。
  • ifge: 如果大于等于0,则跳转。
  • ifgt: 如果大于0,则跳转。
  • ifle: 如果小于等于0,则跳转。
  • goto: 无条件跳转。

方法调用和返回指令

  • invokevirtual: 调用实例方法。
  • invokespecial: 调用私有方法、实例初始化方法或超类的方法。
  • invokestatic: 调用静态方法。
  • invokeinterface: 调用接口方法。
  • invokedynamic: 调用动态绑定的方法。
  • return: 从方法返回,不返回任何值。
  • ireturn: 返回int类型的值。
  • lreturn: 返回long类型的值。
  • freturn: 返回float类型的值。
  • dreturn: 返回double类型的值。
  • areturn: 返回引用类型的值。

异常处理指令

  • athrow: 抛出异常或错误。
  • jsr: 跳转至子程序。
  • ret: 从子程序返回。
  • catch: 捕获异常处理块的开始。

同步指令

  • monitorenter: 进入同步块,获取对象的监视器(锁)。
  • monitorexit: 退出同步块,释放对象的监视器(锁)。

扩展指令

  • wide: 用于扩展局部变量的索引数。
  • multianewarray: 创建多维数组。
  • ifnull: 如果引用为null,则跳转。
  • ifnonnull: 如果引用非null,则跳转。

数组操作指令

  • newarray: 创建一个新的数组并将其引用值压入栈顶。
  • anewarray: 创建一个引用类型的(非原始类型)新数组。
  • arraylength: 获取数组的长度。
  • iaload: 从整型数组加载一个整数到栈顶。
  • laload: 从长整型数组加载一个长整数到栈顶。
  • faload: 从浮点型数组加载一个浮点数到栈顶。
  • daload: 从双精度浮点型数组加载一个双精度浮点数到栈顶。
  • aaload: 从引用类型数组加载一个引用到栈顶。
  • bastore: 将栈顶的布尔或字节值存入指定索引的数组元素中。
  • castore: 将栈顶的字符值存入指定索引的数组元素中。
  • sastore: 将栈顶的短整型值存入指定索引的数组元素中。

指令修饰

  • nop: 什么也不做。
  • iinc: 对局部变量进行自增。

字节码指令的特点

  • 固定大小: 大部分指令是单字节的,这使得指令解码过程高效。
  • 栈操作: JVM是基于栈的虚拟机,大部分指令都是对操作数栈进行操作。
  • 符号引用: 类、方法和字段等的引用在字节码中以符号形式存在,这些符号引用在类加载过程中被解析成直接引用。