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