4

Java 虚拟机指令集

 2 years ago
source link: https://www.diguage.com/post/jvm-instruction-set/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Java 虚拟机指令集

2022-08-31
Java 虚拟机指令集

最近在研究 Java 虚拟机字节码。在 《Java虚拟机规范》 看到一个整理完整的 Java 虚拟机指令集(也叫操作码)列表。转载过来,方便查阅。

现在只是单纯转载,后续有自己的理解时,再逐步丰富内容和解释。

分类操作码助记符指令含义

0x00

nop

什么都不做

0x01

aconst_null

将 null 推送至栈顶

0x02

iconst_m1

将 int 类型 -1 推送至栈顶

0x03

iconst_0

将 int 类型 0 推送至栈顶

0x04

iconst_1

将 int 类型 1 推送至栈顶

0x05

iconst_2

将 int 类型 2 推送至栈顶

0x06

iconst_3

将 int 类型 3 推送至栈顶

0x07

iconst_4

将 int 类型 4 推送至栈顶

0x08

iconst_5

将 int 类型 5 推送至栈顶

0x09

lconst_0

将 long 类型 0 推送至栈顶

0x0a

lconst_1

将 long 类型 1 推送至栈顶

0x0b

fconst_0

将 float 类型 0 推送至栈顶

0x0c

fconst_1

将 float 类型 1 推送至栈顶

0x0d

fconst_2

将 float 类型 2 推送至栈顶

0x0e

dconst_0

将 double 类型 0 推送至栈顶

0x0f

dconst_1

将 double 类型 1 推送至栈顶

0x10

bipush

将单字节的常量值(-128 ~ 127)推送至栈顶

0x11

sipush

将一个短整类型常量值(-32,768 ~ 32,767)推送栈顶

0x12

ldc

将 int、 float 或 String 类型常量值从常量池中推送至栈顶

0x13

ldc_w

将int、 float 或 String 类型常量值从常量池中推送栈顶(宽索引)

0x14

ldc2_w

将 long 或 double 类型常量值从常量池中推送至栈(宽索引)

0x15

iload

将指定的 int 类型本地变量推送至栈顶

0x16

lload

将指定的 long 类型本地变量推送至栈顶

0x17

fload

将指定的 float 类型本地变量推送至栈顶

0x18

dload

将指定的 double 类型本地变量推送至栈顶

0x19

aload

将指定的引用类型本地变量推送至栈顶

0x1a

iload_0

将第 1 个 int 类型本地变量推送至栈顶

0x1b

iload_1

将第 2 个 int 类型本地变量推送至栈顶

0x1c

iload_2

将第 3 个 int 类型本地变量推送至栈顶

0x1d

iload_3

将第 4 个 int 类型本地变量推送至栈顶

0x1e

lload_0

将第 1 个 long 类型本地变量推送至栈顶

0x1f

lload_1

将第 2 个 long 类型本地变量推送至栈顶

0x20

lload_2

将第 3 个 long 类型本地变量推送至栈顶

0x21

lload_3

将第 4 个 long 类型本地变量推送至栈顶

0x22

fload_0

将第 1 个 float 类型本地变量推送至栈顶

0x23

fload_1

将第 2 个 float 类型本地变量推送至栈顶

0x24

fload_2

将第 3 个 float 类型本地变量推送至栈顶

0x25

fload_3

将第 4 个 float 类型本地变量推送至栈顶

0x26

dload_0

将第 1 个 double 类型本地变量推送至栈顶

0x27

dload_1

将第 2 个 double 类型本地变量推送至栈顶

0x28

dload_2

将第 3 个 double 类型本地变量推送至栈顶

0x29

dload_3

将第 4 个 double 类型本地变量推送至栈顶

0x2a

aload_0

将第 1 个引用类型本地变量推送至栈顶

0x2b

aload_1

将第 2 个引用类型本地变量推送至栈顶

0x2c

aload_2

将第 3 个引用类型本地变量推送至栈顶

0x2d

aload_3

将第 4 个引用类型本地变量推送至栈顶

0x2e

iaload

将 int 类型数组的指定元素推送至栈顶

0x2f

laload

将 long 类型数组的指定元素推送至栈顶

0x30

faload

将 float 类型数组的指定元素推送至栈顶

0x31

daload

将 double 类型数组的指定元素推送至栈顶

0x32

aaload

将引用类型数组的指定元素推送至栈顶

0x33

baload

将 boolean 或 byte 类型数组的指定元素推送至栈顶

0x34

caload

将 char 类型数组的指定元素推送至栈顶

0x35

saload

将 short 类型数组的指定元素推送至栈顶

0x36

istore

将栈顶 int 类型数值存入指定本地变量

0x37

lstore

将栈顶 long 类型数值存入指定本地变量

0x38

fstore

将栈顶 float 类型数值存入指定本地变量

0x39

dstore

将栈顶 double 类型数值存入指定本地变量

0x3a

astore

将栈顶引用类型数值存入指定本地变量

0x3b

istore_0

将栈顶 int 类型数值存入第 1 个本地变量

0x3c

istore_1

将栈顶 int 类型数值存入第 2 个本地变量

0x3d

istore_2

将栈顶 int 类型数值存入第 3 个本地变量

0x3e

istore_3

将栈顶 int 类型数值存入第 4 个本地变量

0x3f

lstore_0

将栈顶 long 类型数值存入第 1 个本地变量

0x40

lstore_1

将栈顶 long 类型数值存入第 2 个本地变量

0x41

lstore_2

将栈顶 long 类型数值存入第 3 个本地变量

0x42

lstore_3

将栈顶 long 类型数值存入第 4 个本地变量

0x43

fstore_0

将栈顶 float 类型数值存入第 1 个本地变量

0x44

fstore_1

将栈顶 float 类型数值存入第 2 个本地变量

0x45

fstore_2

将栈顶 float 类型数值存入第 3 个本地变量

0x46

fstore_3

将栈顶 float 类型数值存入第 4 个本地变量

0x47

dstore_0

将栈顶 double 类型数值存入第 1 个本地变量

0x48

dstore_1

将栈顶 double 类型数值存入第 2 个本地变量

0x49

dstore_2

将栈顶 double 类型数值存入第 3 个本地变量

0x4a

dstore_3

将栈顶 double 类型数值存入第 4 个本地变量

0x4b

astore_0

将栈顶引用类型数值存入第 1 个本地变量

0x4c

astore_1

将栈顶引用类型数值存入第 2 个本地变量

0x4d

astore_2

将栈顶引用类型数值存入第 3 个本地变量

0x4e

astore_3

将栈顶引用类型数值存入第 4 个本地变量

0x4f

iastore

将栈顶 int 类型数值存入指定数组的指定索引位置

0x50

lastore

将栈顶 long 类型数值存入指定数组的指定索引位置

0x51

fastore

将栈顶 float 类型数值存入指定数组的指定索引位置

0x52

dastore

将栈顶 double 类型数值存入指定数组的指定索引位置

0x53

aastore

将栈顶引用类型数值存入指定数组的指定索引位置

0x54

bastore

将栈顶 boolean 或 byte 类型数值存入指定数组的指定索引位置

0x55

castore

将栈顶 char 类型数值存入指定数组的指定索引位置

0x56

sastore

将栈顶 short 类型数值存入指定数组的指定索引位置

0x57

pop

将栈顶数值弹出(数值不能是 long 或 double 类型的)

0x58

pop2

将栈顶的一个 long 或 double 类型的数值或两个其他类型的数值弹出

0x59

dup

复制栈顶数值并将复制值压入栈顶

0x5a

dup_x1

复制栈顶值并将其插入栈顶那两个值的下面

0x5b

dup_x2

复制栈顶值并将其插入栈顶那两个或三个值的下面

0x5c

dup2

复制栈顶的一个 long 或 double 类型的值,或两个其他类型的值,并将其压入栈顶

0x5d

dup2_x1

复制栈顶的一个或两个值,并将其插入栈顶那两个或三个值的下面

0x5e

dup2_x2

复制栈顶的一个或两个值,并将其插入栈顶那两个、三个或四个值的下面

0x5f

swap

将栈顶的两个数值互换(数值不能是 long 或 double 类型的)

0x60

iadd

将栈顶两 int 类型数值相加并将结果压入栈顶

0x61

ladd

将栈顶两 1ong 类型数值相加并将结果压入栈顶

0x62

fadd

将栈顶两 float 类型数值相加并将结果压入栈顶

0x63

dadd

将栈顶两 double 类型数值相加并将结果压入栈顶

0x64

isub

将栈顶两 int 类型数值相减并将结果压入栈顶

0x65

lsub

将栈顶两 long 类型数值相减并将结果压入栈顶

0x66

fsub

将栈顶两 float 类型数值相减并将结果压入栈顶

0x67

dsub

将栈顶两 double 类型数值相减并将结果压入栈顶

0x68

imul

将栈顶两 int 类型数值相乘并将结果压入栈顶

0x69

lmul

将栈顶两 long 类型数值相乘并将结果压入栈顶

0x6a

fmul

将栈顶两 float 类型数值相乘并将结果压入栈顶

0x6b

dmul

将栈顶两 double 类型数值相乘并将结果压入栈顶

0x6с

idiv

将栈顶两 int 类型数值相除并将结果压入栈顶

0x6d

ldiv

将栈顶两 long 类型数值相除并将结果压入栈顶

0x6e

fdiv

将栈顶两 float 类型数值相除并将结果压入栈顶

0x6f

ddiv

将栈顶两 double 类型数值相除并将结果压入栈顶

0x70

irem

将栈顶两 int 类型数值作取模运算并将结果压入栈顶

0x71

lrem

将栈顶两 long 类型数值作取模运算并将结果压入栈顶

0x72

frem

将栈顶两 float 类型数值作取模运算并将结果压入栈顶

0x73

drem

将栈顶两 double 类型数值作取模运算并将结果压入栈顶

0x74

ineg

将栈顶 int 类型数值取负并将结果压入栈顶

0x75

lneg

将栈顶 long 类型数值取负并将结果压入栈顶

0x76

fneg

将栈顶 float 类型数值取负并将结果压入栈顶

0x77

dneg

将栈顶 double 类型数值取负并将结果压入栈顶

0x78

ishl

将 int 类型数值左移位指定位数并将结果压入栈顶

0x79

lshl

将 long 类型数值左移位指定位数并将结果压入栈顶

0x7a

ishr

将 int 类型数值(有符号)右移位指定位数并将结果压入栈顶

0x7b

lshr

将 long 类型数值(有符号)右移位指定位数并将结果压入栈顶

iushr

将 int 类型数值(无符号)右移位指定位数并将结果压入栈顶

0x7d

lushr

将 long 类型数值(无符号)右移位指定位数并将结果压入栈顶

0x7e

iand

将栈顶两 int 类型数值作“按位与”并将结果压入栈顶

0x7f

land

将栈顶两 long 类型数值作“按位与”并将结果压入栈顶

0x80

ior

将栈顶两 int 类型数值作“按位或”并将结果压入栈顶

lor

将栈顶两 long 类型数值作“按位或”并将结果压入栈顶

0x82

ixor

将栈顶两 int 类型数值作“按位异或”并将结果压入栈顶

0x83

lxor

将栈顶两 long 类型数值作“按位异或”并将结果压入栈顶

0x84

iinc

将指定 int 类型变量增加指定值(i++i--i += 2)

0x85

i2l

将栈顶 int 类型数值强制转换成 long 类型数值并将结果压入栈顶

0x86

i2f

将栈顶 int 类型数值强制转换成 float 类型数值并将结果压入栈顶

0x87

i2d

将栈顶 int 类型数值强制转换成 double 类型数值并将结果压入栈顶

0x88

l2i

将栈顶 long 类型数值强制转换成 int 类型数值并将结果压入栈顶

0x89

l2f

将栈顶 long 类型数值强制转换成 float 类型数值并将结果压入栈顶

0x8a

l2d

将栈顶 long 类型数值强制转换成 double 类型数值并将结果压入栈顶

0x8b

f2i

将栈顶 float 类型数值强制转换成 int 类型数值并将结果压入栈顶

0x8c

f2l

将栈顶 float 类型数值强制转换成 long 类型数值并将结果压入栈顶

0x8d

f2d

将栈顶 float 类型数值强制转换成 double 类型数值并将结果压入栈顶

0x8e

d2i

将栈顶 double 类型数值强制转换成 int 类型数值并将结果压入栈顶

0x8f

d2l

将栈顶 double 类型数值强制转换成 long 类型数值并将结果压入栈顶

0x90

d2f

将栈顶 double 类型数值强制转换成 float 类型数值并将结果压入栈顶

0x91

i2b

将栈顶 int 类型数值强制转换成 byte 类型数值并将结果压入栈顶

0x92

i2c

将栈顶 int 类型数值强制转换成 char 类型数值并将结果压入栈顶

0x93

i2s

将栈顶 int 类型数值强制转换成 short 类型数值并将结果压入栈顶

0x94

lcmp

比较栈顶两 long 类型数值大小,并将结果(1,0,-1)压入栈顶

0x95

fcmpl

比较栈顶两 float 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将 -1 压入栈顶

0x96

fcmpg

比较栈顶两 float 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将1压入栈顶

0x97

dcmpl

比较栈顶两 double 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将-1压入栈顶

0x98

dcmpg

比较栈顶两 double 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将1压入栈顶

0x99

ifeq

当栈顶 int 类型数值等于 0 时跳转

0x9a

ifne

当栈顶 int 类型数值不等于 0 时跳转

0x9b

iflt

当栈顶 int 类型数值小于 0 时跳转

0x9c

ifge

当栈顶 int 类型数值大于等于 0 时跳转

0x9d

ifgt

当栈顶 int 类型数值大于 0 时跳转

0x9e

ifle

当栈顶 int 类型数值小于等于 0 时跳转

0x9f

if_icmpeq

比较栈顶两 int 类型数值大小,当前者等于后者时跳转

0xa0

if_icmpne

比较栈顶两 int 类型数值大小,当前者不等于后者时跳转

0xa1

if_icmplt

比较栈顶两 int 类型数值大小,当前者小于后者时跳转

0xa2

if_icmpge

比较栈顶两 int 类型数值大小,当前者大于等于后者时跳转

0xa3

if_icmpgt

比较栈顶两 int 类型数值大小,当前者大于后者时跳转

0xa4

if_icmple

比较栈顶两 int 类型数值大小,当前者小于等于后者时跳转

0xa5

if_acmpeq

比较栈顶两引用类型数值,当结果相等时跳转

0xa6

ifacmpne

比较栈顶两引用类型数值,当结果不相等时跳转

0xa7

goto

无条件跳转

0xa8

jsr

跳转至指定 16 位 offset 位置,并将 jsr 下一条指令地址压入栈顶

0xa9

ret

返回至由指定的局部变量所给出的指令位置(一般与 jsr、jsr_w 联合使用)

0xaa

tableswitch

用于 switch 条件跳转,case 值连续(变长指令)

0xab

lookupswitch

用于 switch 条件跳转,case 值不连续(变长指令)

0xac

ireturn

从当前方法返回 int

Oxad

lreturn

从当前方法返回 long

0xae

freturn

从当前方法返回 float

0xaf

dreturn

从当前方法返回 double

0xb0

areturn

从当前方法返回对象引用

0xb1

return

从当前方法返回void

0xb2

getstatic

获取指定类的静态字段,并将其值压入栈顶

0xb3

putstatic

为指定类的静态字段赋值

0xb4

getfield

获取指定类的实例字段,并将其值压入栈顶

0xb5

putfield

为指定类的实例字段赋值

0xb6

invokevirtual

调用实例方法

0xb7

invokespecial

调用父类方法、实例初始化方法、私有方法

0xb8

invokestatic

调用静态方法

0xb9

invokeinterface

调用接口方法

0xba

invokedynamic

调用动态链接方法

0xbb

new

创建一个对象,并将其引用值压入栈顶

0xbc

newarray

创建一个指定原始类型(如int、float 、char等)的数组,并将其引用值压入栈顶

0xbd

anewarray

创建一个引用型(如类、接口、数组)的数组,并将其引用值压入栈顶

0xbe

arraylength

获得数组的长度值并压入栈顶

0xbf

athrow

将栈顶的异常抛出

checkcast

检验类型转换,检验未通过将抛出 ClassCastException

instanceof

检验对象是否是指定类的实例。如果是,就将 1 压入栈顶,否则将 0 压入栈顶

0xc2

monitorenter

获得对象的锁,用于实现同步块

0xc3

monitorexit

释放对象的锁,用于实现同步块

0xc4

wide

扩展本地变量索引的宽度

0xс5

multianewarray

创建指定类型和指定维度的多维数组(执行该指令时,操作栈中必须包含各维度的长度值),并将其引用值压入栈顶

0xc6

ifnull

为nu11时跳转

0xc7

ifnonnull

不为nu11时跳转

0xc8

goto_w

无条件跳转(宽索引)

0xc9

jsr_w

跳转至指定 32 位 offset 位置,并将 jsr_w 下一条指令地址压入栈顶

Оxca

breakpoint

调试时的断点标记

Oxfe

impdep1

为特定软件面预留的语言后门

0xff

impdep2

为特定硬件面预留的语言后门

看在D瓜哥码字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

微信打赏码
支付宝打赏码

欢迎关注D瓜哥的微信公众号,在公众号可以获取我的微信二维码:

微信公众号
公众号的微信号是: jikerizhi。如果图片加载不出来,可以直接通过搜索公众号的微信号来查找D瓜哥的公众号。
来说两句吧...
我来说两句

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK