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是基于栈的虚拟机,大部分指令都是对操作数栈进行操作。
- 符号引用: 类、方法和字段等的引用在字节码中以符号形式存在,这些符号引用在类加载过程中被解析成直接引用。