字节码指令

下面会指令族的概念,先说明一下

前缀x取值

含义

i

int

b

byte

c

char

s

short

l

long

f

float

d

double

a

对象引用

这里没有boolean类型的,他的操作指令同int,以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
 

 

package com.test.a;

public class Test{
    public void method1(){
        int v1=0;
        boolean v2=true; 
    }
}

 

 

常量入操作数栈

const系列

用于将特定的常量压入操作数栈,常量就包含在指令中,

iconst_1iconst_2iconst_3int 123压入操作数栈中iconst_m1-1压入操作数栈

lconst_0long 0压入操作数栈

dconst_0double 0压入操作数栈

aconst_nullnull压入操作数栈

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
 

 

package com.test.b;

public class Test{
    public void method1(){
        int v1=0;
    }
}

 

push系列

bipush接收8位整数作为参数,sipush接收16位整数作为参数,将参数压入栈中

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
 

 

package com.test.c;

public class Test{
    public void method1(){
        int v1=100;
    }
}

 

 

 

ldc

ldc接收一个参数,该参数指向常量池中的intfloatString等的索引,将指定的元素压入操作数栈

ldc2_w接收一个参数,该参数指向常量池中的longdouble等的索引

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
 

 

package com.test.d;

public class Test{
    public void method1(){
        float v1=100f;
        double v2=100d;
    }
}

 

 

出栈赋值局部变量表

store系列

istore_1从操作数栈中弹出一个int,将它赋值给局部变量表中的第1个局部变量istore_2从操作数栈中弹出一个int赋值给第2个局部变量

lstore_1从操作数栈中弹出一个long赋值给第1个局部变量

xstore接收一个位置参数,从操作数栈中弹出一个数据,将其赋值给指定位置的局部变量

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
9
10
 

 

package com.test.e;

public class Test{
    public void method1(){
        float v1=100f;
        double v2=100d;
        int v3=0;
        int v4=0;
    }
}

注意后面的istore 4istore 5,其位置参数指的是局部变量表的槽位

 

局部变量操作数栈

load系列

iload_0fload_0表示将第0个局部变量压入操作数栈(只不过局部变量表中的数据类型不同)

aload_0表示将第0个局部变量压入操作数栈,0个局部变量为对象引用

xload接收一个位置参数,将指定位置的局部变量压入操作数栈

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
 

 

package com.test.f;

public class Test{
    public void method1(int arg1, int arg2, int arg3, double arg4){
        int v1=arg1;
        double v2=arg4;
    }
}

 

 

对象操作

创建

指令new用于创建对象,其接收一个参数,指向常量池中的类名的索引,执行完成后将新创建对象的引用压入操作数栈

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
 

 

package com.test.g;

public class TestA{
    public void method1(){
        TestB v1=new TestB();
    }
}

字段访问

putfield用于设置实例对象的字段要求此时操作数栈的栈顶为要设置的数据,次栈顶为要设置的对象的引用,接收一个参数为要设置的字段的名称

操作完成以后弹出栈顶、次栈顶

getfield用于获取实例对象的字段,要求此时操作数栈的栈顶为要获取的对象的引用,接收一个参数为要获取的字段的名称

操作完成以后弹出栈顶,将获取到的数据压入操作数栈

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
9
10
 

 

package com.test.h;

public class TestA{
    public void method1(){
        TestB v1=new TestB();
        v1.m1=200;
        
        int v2=v1.m1;
    }
}

 

 

putstaticgetstatic用于访问类字段

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
9
 

 

package com.test.i;

public class TestA{
    public void method1(){
        TestB.m1=200;
        
        int v1=TestB.m1;
    }
}

 

 

函数调用

函数调用都是通过invoke指令进行的

invokespecial:调用一些特殊的方法如构造函数、私有方法、父类的方法,这些方法都是静态绑定的

invokestatic:调用静态方法,也是静态绑定的

invokevirtual:调用对象的实例方法,会根据对象的实际类型进行派发,支持动态调用,是最常用的调用方式

invokeinterface:调用接口的方法也支持动态调用

 

invokevirtual为例,操作时要求操作数栈的栈顶为参数,次栈顶为要操作的对象,参数为要调用的方法的名称

操作完成以后弹出栈顶元素,将结果压入操作数栈

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
 

 

package com.test.j;

public class TestA{
    public void method1(){
        TestB v1=new TestB();
        int v2=v1.method1(100, 100);
    }
}

 

数组

使用newarray创建基本类型的数组,使用anewarray创建对象类型的数组

使用xastore给数组项赋值,操作时要求操作数栈的栈顶依次值、索引、数组引用,操作完成会弹出栈顶元素

使用xaload获取数组项,操作时要求操作数栈的栈顶为索引、数组引用,操作完成会弹出栈顶元素,并将数组项压入操作数栈。

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
9
 

 

package com.test.k;

public class Test{
    public void method1(){
        int[] v1=new int[10];
        v1[0]=100;
        int v2=v1[0];
    }
}

 

 

duppop

dup意为duplicate复制,他会将栈顶元素复制一份并再次压入操作数栈

pop将栈顶元素弹出操作数栈

以如下代码为例

 Java Code 

1
2
3
4
5
6
7
8
 

 

package com.test.l;

public class Test{
    public void method1(){
        Object obj=new Object();
        obj.toString();
    }
}

 

 

new指令完成以后,栈顶只有一份对象引用

但是后续对给对象连续进行两次操作,一次通过invokespecial调用构造函数,一次通过astore将栈顶元素赋值给局部变量

这两个操作都会将栈顶元素弹出,故为了连续两次使用相同的栈顶元素,使用dup指令复制了一份对象引用

 

return

当函数要返回时,需要将返回值压入到调用者的操作数栈,此时需要使用xreturn指令

当返回值为void时,使用return指令,当返回值为int时,使用ireturn指令

 

运算

 

比较控制

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值