JVM 常用指令
指令集分类:
基于栈的指令集 (操作数栈) 设计简单
基于寄存器的指令集(汇编、hotspot的local variable table) 设计较复杂、速度快
两个指令集硬件上都是基于寄存器的
bipush 8 压栈8 把操作数8放到栈中
astore_1 弹出栈顶元素,赋值给本地变量表1位置的变量
istore_8 出栈 取栈顶数据放到局部变量表2位置
main 的 局部变量表 0 位置数据是 args
非静态方法第0个位置是 this,之后依次是入参
静态方法第0个位置是入参
iload_2 入栈 从局部变量表为2位置的数拿出来,压栈,放到栈中
iinc 1 by 2 把局部变量表中2位置的数+1
return 返回局部变量表中的值(栈帧顶部)
例子: int i = 200
sipush 200 ( 200>127 所有不能用bipush,而是sipush)
b 代表byte s 代表short.
再扩展为int类型再压栈
istore_1
return
整型
byte 1字节
short 2字节
int 4字节
long 8字节
浮点型
float 4字节
double 8字节
布尔型
boolean 1字节
字符型
char 2字节
例子: int c=a+b
iload_1 a入栈
iload_2 b入栈
iadd 弹出栈顶两个元素并相加
istore_3 相加结果入栈
return 返回栈顶元素
new 申请内存,赋默认值 此时对象半初始化状态!!!!!!!!!!!!!
dup (duplication)
在堆内存里new一个对象,赋默认值,其地址会压栈
dup复制这个对象的地址,,则dup也指向这个对象
复制这个地址的目的是invokespecial需要弹出栈顶元素执行构造方法,会用掉一个引用
iconst_1 把常量 1 压栈
if_icmpne 弹出两个数比较
compare
if i ==1
if_icmpne 7*(+5)
出栈两个数进行比较,如果相等,进入下标为7的指令,否则进入下标为5的指令
isub 弹出两个数相减
iadd 弹出两个数相加
imul 弹出两个数相乘
invoke 指令分类
invokeSpecial 可以直接定位的,不需要多态的非静态方法,如 private的方法,只有本类有,可以直接定位
<init> 构造方法 对象完全初始化状态!!!!!赋初始值,执行构造方法
<clinit>构造语句块
private修饰的方法
incokeVirtual 执行非静态方法(自带多态)
invokeInterface 接口的实现对象调用
List list=new ArrayList()
list调用方法是用 invokeInterface
ArrayList list=new ArrayList()
此时用的是 invokeVIrtual
invokeStatic 执行静态方法
invokeDynamic 执行lambda表达式;反射;
其他动态语言scala kotlin CGLib ASM 等动态产生的class会用到这个指令