【Java】JVM指令集

编程入门 行业动态 更新时间:2024-10-09 04:15:57

【Java】JVM<a href=https://www.elefans.com/category/jswz/34/1766218.html style=指令集"/>

【Java】JVM指令集

文章目录

  • 数据存取
    • 从常量池取值并入栈
    • 从局部变量取值并入栈
    • 从栈取值并存入局部变量
    • 栈基本操作
  • 数值类型操作
    • 数值运算
      • 数值算术运算
      • 数值移位运算
      • 数值逻辑运算
      • 数值比较运算
    • 数值类型转换
  • 对象类型操作
  • 数组类型操作
  • 流程控制
    • 条件比较判断
    • 无条件跳转
    • 跳转表跳转
  • 方法执行
    • 方法调用
    • 方法返回
  • 异常处理
  • 线程同步
  • 其他操作
  • 指令总结
  • 官方文档

数据存取

从常量池取值并入栈

JVM的const系列指令是用于将常量值从常量池中加载到操作数栈中的指令。常量池是一个与类或接口相关联的表,其中包含各种常量值、符号引用等信息。在编译Java代码时,常量值通常会直接嵌入到代码中,而符号引用则会转化为对应的常量池索引。

这些指令可以用于直接操作常量值,从而方便地进行数值计算、字符串操作等。值得注意的是,const系列指令只能加载常量值,不能加载局部变量或数组元素等非常量值。

JVM指令指令操作Classfile常量Classfile指令编号
aconst_null将null对象引用压入栈ACONST_NULL1
iconst_m1将int类型常量-1压入栈ICONST_M12
iconst_0将int类型常量0压入栈ICONST_03
iconst_1将int类型常量1压入栈ICONST_14
iconst_2将int类型常量2压入栈ICONST_25
iconst_3将int类型常量3压入栈ICONST_36
iconst_4将int类型常量4压入栈ICONST_47
iconst_5将int类型常量5压入栈ICONST_58
lconst_0将long类型常量0压入栈LCONST_09
lconst_1将long类型常量1压入栈LCONST_110
fconst_0将float类型常量0压入栈FCONST_011
fconst_1将float类型常量1压入栈FCONST_112
fconst_2将float类型常量2压入栈FCONST_213
dconst_0将double类型常量0压入栈DCONST_014
dconst_1将double类型常量1压入栈DCONST_115
bipush将一个8位带符号整数压入栈BIPUSH16
sipush将16位带符号整数压入栈SIPUSH17
ldc把常量池中的项压入栈LDC18
ldc_w把常量池中的项压入栈(使用宽索引)LDC_W19
ldc2_w把常量池中long类型或者double类型的项压入栈(使用宽索引)LDC2_W20

从局部变量取值并入栈

在JVM中,局部变量是一段被分配给方法的栈内存。JVM会将方法参数、临时变量、方法返回值等存储在局部变量中。当JVM需要使用一个局部变量的值时,它需要进行load操作,将该值从局部变量表中加载到操作数栈中。

load操作是根据局部变量的类型来执行的,例如load操作可以是iload、fload、aload等。这些操作指令对应了不同类型的局部变量,比如iload对应int类型的局部变量,fload对应float类型的局部变量,aload对应引用类型的局部变量等。

在load操作中,JVM会使用索引来访问局部变量表中的某个变量,并将其压入操作数栈中。这个索引是一个从0开始的整数,表示局部变量表中的第几个位置。需要注意的是,JVM在load操作之前需要先检查该变量是否已经被正确初始化,如果变量没有被初始化或者该索引超出了局部变量表的范围,JVM将会抛出一个异常。

JVM指令指令操作Classfile常量Classfile指令编号
iload从局部变量中装载int类型值ILOAD21
lload从局部变量中装载long类型值LLOAD22
fload从局部变量中装载float类型值FLOAD23
dload从局部变量中装载double类型值DLOAD24
aload从局部变量中装载引用类型值ALOAD25
iload_0从局部变量0中装载int类型值ILOAD_026
iload_1从局部变量1中装载int类型值ILOAD_127
iload_2从局部变量2中装载int类型值ILOAD_228
iload_3从局部变量3中装载int类型值ILOAD_329
lload_0从局部变量0中装载long类型值LLOAD_030
lload_1从局部变量1中装载long类型值LLOAD_131
lload_2从局部变量2中装载long类型值LLOAD_232
lload_3从局部变量3中装载long类型值LLOAD_333
fload_0从局部变量0中装载float类型值FLOAD_034
fload_1从局部变量1中装载float类型值FLOAD_135
fload_2从局部变量2中装载float类型值FLOAD_236
fload_3从局部变量3中装载float类型值FLOAD_337
dload_0从局部变量0中装载double类型值DLOAD_038
dload_1从局部变量1中装载double类型值DLOAD_139
dload_2从局部变量2中装载double类型值DLOAD_240
dload_3从局部变量3中装载double类型值DLOAD_341
aload_0从局部变量0中装载引用类型值ALOAD_042
aload_1从局部变量1中装载引用类型值ALOAD_143
aload_2从局部变量2中装载引用类型值ALOAD_244
aload_3从局部变量3中装载引用类型值ALOAD_345
iaload从数组中装载int类型值IALOAD46
laload从数组中装载long类型值LALOAD47
faload从数组中装载float类型值FALOAD48
daload从数组中装载double类型值DALOAD49
aaload从数组中装载引用类型值AALOAD50
baload从数组中装载byte类型或boolean类型值BALOAD51
caload从数组中装载char类型值CALOAD52
saload从数组中装载short类型值SALOAD53

从栈取值并存入局部变量

JVM支持将栈顶的值存储到当前方法的局部变量表中的某个位置上。这个过程需要指定存储到哪个位置,以及该位置所需的数据类型。

在JVM中,局部变量表是用来存储方法中的参数和局部变量的表格,每个局部变量表的位置都有一个编号,从0开始递增。在执行方法时,JVM会为方法分配一个局部变量表,并根据方法的参数和局部变量数量确定表格的大小。

当JVM需要从栈中store值到局部变量表时,需要指定存储到哪个位置,通常是通过局部变量表中的位置编号来指定。

JVM在执行store指令时,会将栈顶的值弹出,存储到指定的局部变量表位置上,并将该位置上的值的类型标记为已初始化。如果存储到的位置上已经存在一个值,该值将被覆盖。同时,如果指定的位置在局部变量表范围之外,或者存储的值与指定的位置所需的数据类型不匹配,将会抛出相应的异常。

JVM指令指令操作Classfile常量Classfile指令编号
istore将int类型值存入局部变量ISTORE54
lstore将long类型值存入局部变量LSTORE55
fstore将float类型值存入局部变量FSTORE56
dstore将double类型值存入局部变量DSTORE57
astore将引用类型或returnAddress类型值存入局部变量ASTORE58
istore_0将int类型值存入局部变量0ISTORE_059
istore_1将int类型值存入局部变量1ISTORE_160
istore_2将int类型值存入局部变量2ISTORE_261
istore_3将int类型值存入局部变量3ISTORE_362
lstore_0将long类型值存入局部变量0LSTORE_063
lstore_1将long类型值存入局部变量1LSTORE_164
lstore_2将long类型值存入局部变量2LSTORE_265
lstore_3将long类型值存入局部变量3LSTORE_366
fstore_0将float类型值存入局部变量0FSTORE_067
fstore_1将float类型值存入局部变量1FSTORE_168
fstore_2将float类型值存入局部变量2FSTORE_269
fstore_3将float类型值存入局部变量3FSTORE_370
dstore_0将double类型值存入局部变量0DSTORE_071
dstore_1将double类型值存入局部变量1DSTORE_172
dstore_2将double类型值存入局部变量2DSTORE_273
dstore_3将double类型值存入局部变量3DSTORE_374
astore_0将引用类型或returnAddress类型值存入局部变量0ASTORE_075
astore_1将引用类型或returnAddress类型值存入局部变量1ASTORE_176
astore_2将引用类型或returnAddress类型值存入局部变量2ASTORE_277
astore_3将引用类型或returnAddress类型值存入局部变量3ASTORE_378
iastore将int类型值存入数组中IASTORE79
lastore将long类型值存入数组中LASTORE80
fastore将float类型值存入数组中FASTORE81
dastore将double类型值存入数组中DASTORE82
aastore将引用类型值存入数组中AASTORE83
bastore将byte类型或者boolean类型值存入数组中BASTORE84
castore将char类型值存入数组中CASTORE85
sastore将short类型值存入数组中SASTORE86

栈基本操作

JVM指令指令操作Classfile常量Classfile指令编号
nop不做任何操作NOP0
pop弹出栈顶端1个字长的内容POP87
pop2弹出栈顶端2个字长的内容POP288
dup复制栈顶部1个字长内容DUP89
dup_x1复制栈顶部1个字长的内容,然后将复制内容及原来弹出的2个字长的内容压入栈DUP_X190
dup_x2复制栈顶部1个字长的内容,然后将复制内容及原来弹出的3个字长的内容压入栈DUP_X291
dup2复制栈顶部2个字长内容DUP292
dup2_x1复制栈顶部2个字长的内容,然后将复制内容及原来弹出的3个字长的内容压入栈DUP2_X193
dup2_x1复制栈顶部2个字长的内容,然后将复制内容及原来弹出的4个字长的内容压入栈DUP2_X294
swap交换栈顶部两个字长内容SWAP95

数值类型操作

数值运算

数值算术运算

JVM指令指令操作Classfile常量Classfile指令编号
iadd执行int类型的加法IADD96
ladd执行long类型的加法LADD97
fadd执行float类型的加法FADD98
dadd执行double类型的加法DADD99
isub执行int类型的减法ISUB100
lsub执行long类型的减法LSUB101
fsub执行float类型的减法FSUB102
dsub执行double类型的减法DSUB103
imul执行int类型的乘法IMUL104
lmul执行long类型的乘法LMUL105
fmul执行float类型的乘法FMUL106
dmul执行double类型的乘法DMUL107
idiv执行int类型的除法IDIV108
ldiv执行long类型的除法LDIV109
fdiv执行float类型的除法FDIV110
ddiv执行double类型的除法DDIV111
irem计算int类型除法的余数IREM112
lrem计算long类型除法的余数LREM113
frem计算float类型除法的余数FREM114
drem计算double类型除法的余数DREM115
ineg对一个int类型值进行取反操作INEG116
lneg对一个long类型值进行取反操作LNEG117
fneg将一个float类型的数值取反FNEG118
dneg将一个double类型的数值取反DNEG119
iinc把一个常量值加到一个int类型的局部变量上IINC132

数值移位运算

JVM指令指令操作Classfile常量Classfile指令编号
ishl执行int类型的向左移位操作ISHL120
lshl执行long类型的向左移位操作LSHL121
ishr执行int类型的向右移位操作ISHR122
lshr执行long类型的向右移位操作LSHR123
iushr执行int类型的向右逻辑移位操作IUSHR124
lushr执行long类型的向右逻辑移位操作LUSHR125

数值逻辑运算

JVM指令指令操作Classfile常量Classfile指令编号
iand对int类型值进行“逻辑与”操作IAND126
land对long类型值进行“逻辑与”操作LAND127
ior对int类型值进行“逻辑或”操作IOR128
lor对long类型值进行“逻辑或”操作LOR129
ixor对int类型值进行“逻辑异或”操作IXOR130
lxor对long类型值进行“逻辑异或”操作LXOR131

数值比较运算

JVM指令指令操作Classfile常量Classfile指令编号
lcmp比较long类型值LCMP148
fcmpl比较float类型值(当遇到NaN时,返回-1)FCMPL149
fcmpg比较float类型值(当遇到NaN时,返回1)FCMPG150
dcmpl比较double类型值(当遇到NaN时,返回-1)DCMPL151
dcmpg比较double类型值(当遇到NaN时,返回1)DCMPG152

数值类型转换

JVM指令指令操作Classfile常量Classfile指令编号
i2l把int类型的数据转化为long类型I2L133
i2f把int类型的数据转化为float类型I2F134
i2d把int类型的数据转化为double类型I2D135
l2i把long类型的数据转化为int类型L2I136
l2f把long类型的数据转化为float类型L2F137
l2d把long类型的数据转化为double类型L2D138
f2i把float类型的数据转化为int类型F2I139
f2l把float类型的数据转化为long类型F2L140
f2d把float类型的数据转化为double类型F2D141
d2i把double类型的数据转化为int类型D2I142
d2l把double类型的数据转化为long类型D2L143
d2f把double类型的数据转化为float类型D2F144
i2b把int类型的数据转化为byte类型I2B145
i2c把int类型的数据转化为char类型I2C146
i2s把int类型的数据转化为short类型I2S147

对象类型操作

JVM指令指令操作Classfile常量Classfile指令编号
new创建一个新对象NEW187
getstatic从类中获取静态字段GETSTATIC178
putstatic设置类中静态字段的值PUTSTATIC179
getfield从对象中获取字段GETFIELD180
putfield设置对象中字段的值PUTFIELD181
checkcast确定对象为所给定的类型CHECKCAST192
instanceof判断对象是否为给定的类型INSTANCEOF193

数组类型操作

JVM指令指令操作Classfile常量Classfile指令编号
newarray分配数据成员类型为基本上数据类型的新数组NEWARRAY188
anewarray分配数据成员类型为引用类型的新数组ANEWARRAY189
arraylength获取数组长度ARRAYLENGTH190
multianewarray分配新的多维数组MULTIANEWARRAY197

流程控制

条件比较判断

JVM指令指令操作Classfile常量Classfile指令编号
ifeq如果等于0,则跳转IFEQ153
ifne如果不等于0,则跳转IFNE154
iflt如果小于0,则跳转IFLT155
ifge如果大于等于0,则跳转IFGE156
ifgt如果大于0,则跳转IFGT157
ifle如果小于等于0,则跳转IFLE158
if_icmpeq如果两个int值相等,则跳转IF_ICMPEQ159
if_icmpne如果两个int类型值不相等,则跳转IF_ICMPNE160
if_icmplt如果一个int类型值小于另外一个int类型值,则跳转IF_ICMPLT161
if_icmpge如果一个int类型值大于或者等于另外一个int类型值,则跳转IF_ICMPGE162
if_icmpgt如果一个int类型值大于另外一个int类型值,则跳转IF_ICMPGT163
if_icmple如果一个int类型值小于或者等于另外一个int类型值,则跳转IF_ICMPLE164
if_acmpeq如果两个对象引用相等,则跳转IF_ACMPEQ165
if_acmpnc如果两个对象引用不相等,则跳转IF_ACMPNE166
ifnull如果等于null,则跳转IFNULL198
ifnonnull如果不等于null,则跳转IFNONNULL199

无条件跳转

JVM指令指令操作Classfile常量Classfile指令编号
goto无条件跳转GOTO167
goto_w无条件跳转(宽索引)GOTO_W200

跳转表跳转

JVM指令指令操作Classfile常量Classfile指令编号
tableswitch通过索引访问跳转表,并跳转TABLESWITCH170
lookupswitch通过键值匹配访问跳转表,并执行跳转操作LOOKUPSWITCH171

方法执行

方法调用

JVM提供invoke指令用于方法调用。这些指令的调用会导致操作数栈和局部变量表的改变,具体的改变取决于调用的方法的返回值和参数类型。这些指令的使用要遵循特定的规则,包括参数类型和数量的匹配,访问权限等。在JVM执行过程中,这些规则的违反将导致指令无法正常执行并抛出异常。

JVM指令指令操作Classfile常量Classfile指令编号
invokevirtual运行时按照对象的类来调用实例方法INVOKEVIRTUAL182
invokespecial根据编译时类型来调用实例方法INVOKESPECIAL183
invokestatic调用静态方法INVOKESTATIC184
invokeinterface调用接口方法INVOKEINTERFACE185
invokedynamic调用运行时动态绑定方法INVOKEDYNAMIC186

方法返回

JVM指令指令操作Classfile常量Classfile指令编号
ireturn从方法中返回int类型的数据IRETURN172
lreturn从方法中返回long类型的数据LRETURN173
freturn从方法中返回float类型的数据FRETURN174
dreturn从方法中返回double类型的数据DRETURN175
areturn从方法中返回引用类型的数据ARETURN176
return从方法中返回,返回值为voidRETURN177

异常处理

JVM指令指令操作Classfile常量Classfile指令编号
jsr跳转到子例程JSR168
ret从子例程返回RET169
athrow抛出异常或错误ATHROW191
jsr_w跳转到子例程(宽索引)JSR_W201

线程同步

JVM指令指令操作Classfile常量Classfile指令编号
montiorenter进入并获取对象监视器MONITORENTER194
monitorexit释放并退出对象监视器MONITOREXIT195

其他操作

JVM指令指令操作Classfile常量Classfile指令编号
wide使用附加字节扩展局部变量索引WIDE196

指令总结

下表总结了JVM指令集中的类型支持。通过用类型列中的字母替换操作码列中指令模板中的T来构建具有类型信息的特定指令。如果某些指令模板和类型的类型列为空白,则不存在支持该类型操作的指令。比如int类型有加载指令iload,而byte类型没有加载指令。

JVM指令byteshortintlongfloatdoublecharreference
Tipushbipushsipush
Tconsticonstlconstfconstdconstaconst
Tloadiloadlloadfloaddloadaload
Tstoreistorelstorefstoredstoreastore
Tinciinc
Taloadbaloadsaloadialoadlaloadfaloaddaloadcaloadaaload
Tastorebastoresastoreiastorelastorefastoredastorecastoreaastore
Taddiaddladdfadddadd
Tsubisublsubfsubdsub
Tmulimullmulfmuldmul
Tdividivldivfdivddiv
Tremiremlremfremdrem
Tnegineglnegfnegdneg
Tshlishllshl
Tshrishrlshr
Tushriushrlushr
Tandiandland
Toriorlor
Txorixorlxor
i2Ti2bi2si2li2fi2d
l2Tl2il2fl2d
f2Tf2if2lf2d
d2Td2id2ld2f
Tcmplcmp
Tcmplfcmpldcmpl
Tcmpgfcmpgdcmpg
if_TcmpOPif_icmpOPif_acmpOP
Treturnireturnlreturnfreturndreturnareturn

官方文档

推荐阅读:JDK20官方文档-JVM指令集

更多推荐

【Java】JVM指令集

本文发布于:2024-02-13 09:01:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1757487.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指令集   Java   JVM

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!