0
点赞
收藏
分享

微信扫一扫

JVM指令详解(上)


一、未归类系列A

此系列暂未归类。

指令码    助记符                            说明

0x00

0x01

二、const系列

该系列命令主要负责把简单的数值类型送到栈顶。该系列命令不带参数。注意只把简单的数值类型送到栈顶时,才使用如下的命令。

比如对应int型才该方式只能把-1,0,1,2,3,4,5(分别采用iconst_m1,iconst_0, iconst_1, iconst_2, iconst_3, iconst_4, iconst_5)

送到栈顶。对于int型,其他的数值请使用push系列命令(比如bipush)。

指令码    助记符                            说明

0x02         iconst_m1

0x03

0x04

0x05

0x06

0x07

0x08

0x09         lconst_0

0x0a

0x0b         fconst_0 

0x0c

0x0d

0x0e         dconst_0

0x0f 

三、push系列

该系列命令负责把一个整形数字(长度比较小)送到到栈顶。该系列命令有一个参数,用于指定要送到栈顶的数字。

注意该系列命令只能操作一定范围内的整形数值,超出该范围的使用将使用ldc命令系列。

指令码    助记符                            说明

0x10 

0x11

四、ldc系列

该系列命令负责把数值常量或String常量值从常量池中推送至栈顶。该命令后面需要给一个表示常量在常量池中位置(编号)的参数,

哪些常量是放在常量池呢?比如:final static int id=32768;final static float double=6.5。

对于const系列命令和push系列命令操作范围之外的数值类型常量,都放在常量池中.

另外,所有不是通过new创建的String都是放在常量池中的。

指令码    助记符                               说明

0x12

0x13

0x14

五、load系列

5.1、load系列A

该系列命令负责把本地变量的送到栈顶。这里的本地变量不仅可以是数值类型,还可以是引用类型。

对于前四个本地变量可以采用iload_0,iload_1,iload_2,iload_3(它们分别表示第0,1,2,3个整形变量)这种不到参数的简化命令形式。

对于第4以上的本地变量将使用iload命令这种形式,在它后面给一参数,以表示是对第几个(从0开始)本类型的本地变量进行操作。

对本地变量所进行的编号,是对所有类型的本地变量进行的(并不按照类型分类)。

对于非静态函数,第一变量是this,即其对于的操作是aload_0.

还有函数传入参数也算本地变量,在进行编号时,它是先于函数体的本地变量的。

指令码    助记符                                        说明

0x15 

0x16

0x17

0x18

0x19

0x1a

0x1b

0x1c

0x1d

0x1e

0x1f

0x20

0x21

0x22

0x23

0x24

0x25

0x26

0x27

0x28

0x29

0x2a

0x2b

0x2c

0x2d

5.2、load系列B

该系列命令负责把数组的某项送到栈顶。该命令根据栈里内容来确定对哪个数组的哪项进行操作。

比如,如果有成员变量:final String names[]={"robin","hb"};

那么这句话:String str=names[0];对应的指令为

   17:aload_0                                                            //将this引用推送至栈顶,即压入栈。

   18:getfield #5; //Field names:[Ljava/lang/String;//将栈顶的指定的对象的第5个实例域(Field)的值(这个值可能是引用,这里就是引用)压入栈顶

   21:iconst_0                                                            //数组的索引值(下标)推至栈顶,即压入栈

   22:aaload                                                              //根据栈里内容来把name数组的第一项的值推至栈顶

   23:astore 5                                                       //把栈顶的值存到str变量里。因为str在我的程序中是其所在非静态函数的第5个变量(从0开始计数),

指令码    助记符                               说明

0x2e

0x2f

0x30

0x31

0x32

0x33

0x34

0x35

六、store系列

6.1、store系列A

该系列命令负责把栈顶的值存入本地变量。这里的本地变量不仅可以是数值类型,还可以是引用类型。

如果是把栈顶的值存入到前四个本地变量的话,采用的是istore_0,istore_1,istore_2,istore_3(它们分别表示第0,1,2,3个本地整形变量)这种不到参数的简化命令形式。如果是把栈顶的值存入到第四个以上本地变量的话,将使用istore命令这种形式,在它后面给一参数,以表示是把栈顶的值存入到第几个(从0开始)本地变量中。

对本地变量所进行的编号,是对所有类型的本地变量进行的(并不按照类型分类)。

对于非静态函数,第一变量是this,它是只读的.

还有函数传入参数也算本地变量,在进行编号时,它是先于函数体的本地变量的。

指令码    助记符                               说明

0x36

0x37

0x38

0x39

0x3a

0x3b

0x3c

0x3d

0x3e

0x3f

0x40

0x41

0x42

0x43

0x44

0x45

0x46

0x47 

0x48

0x49

0x4a

0x4b

0x4c

0x4d

0x4e

6.2、store系列B

该系列命令负责把栈顶项的值存到数组里。该命令根据栈里内容来确定对哪个数组的哪项进行操作。

比如,如下代码:

int moneys[]=new int[5];

moneys[1]=100;

其对应的指令为:

   49:iconst_5

   50:newarray int

   52:astore 11

   54:aload11

   56:iconst_1

   57:bipush100

   59:iastore

   60:lload 6       //因为str在我的程序中是其所非静态在函数的第6个变量(从0开始计数).

指令码    助记符                                   说明

0x4f 

0x50

0x51

0x52

0x53

0x54

0x55

0x56

七、pop系列

该系列命令似乎只是简单对栈顶进行操作,更多详情待补充。

指令码     助记符                                   说明

0x57

0x58

0x59

0x5a

0x5b

0x5c

0x5d

0x5e

八、栈顶元素数学操作及移位操作系列

该系列命令用于对栈顶元素行数学操作,和对数值进行移位操作。移位操作的操作数和要移位的数都是从栈里取得。

比如对于代码:int k=100;k=k>>1;其对应的JVM指令为:

   60:bipush 100

   62:istore 12//因为k在我的程序中是其所在非静态函数的第12个变量(从0开始计数).

   64:iload 12

   66:iconst_1

   67:ishr

   68:istore 12

指令码     助记符                                        说明

0x5f

0x60

0x61

0x62

0x63

0x64

0x65

0x66

0x67

0x68

0x69

0x6a

0x6b

0x6c

0x6d

0x6e

0x6f

0x70

0x71

0x72

0x73

0x74

0x75

0x76

0x77

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

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

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

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

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

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

0x7e

0x7f

0x80

0x81

0x82

0x83

举报

相关推荐

0 条评论