Java虚拟机-字节码指令

2019-08-04  本文已影响0人  贪睡的企鹅

1 字节码指令

Java字节码指令的执行离不开操作数栈,局部变量表,和常量池。

2 常量池

对于字节码指定来说,常量池中的常量可以用来来描述一个类字段,类,接口,方法的。也可以用来表示一个基本类型数据,如字符串,数字等。当我们执行一个指令的时候通常会带上一个或多个常量常量作为操作数,用来表示指定所作用的目标。

案例

//ldc指令用来将常量池中指定的常量放入操作数栈中,这里指定的常量是#2
ldc           #2


/**
*invokestatic指令用来调用类中静态方法。如果调用的静态方法描述中需要传入参数,则会将当前操作数栈顶元素作为方法的参数,并从操作数中出栈,静态方法执行完毕会将返回值推到操作数栈中。静态方法用常量池中常量来表示,该常量类型是一个方法的符号引用。
**/
invokestatic  #3 
image

3 操作数栈

每一个Java字节码指令的执行和操作数栈密不可分。操作栈是用来存储指令计算中参数和结果数据结构。在指令执行执行前我们会将要操作的数据放入栈中。执行中会将操作栈中的数据会取出计算,并将指令执行结果写入栈中。

3-1 静态变量初始化

如下指定完成了静态变量staticField初始化

0: ldc           #10                 // String 静态变量
2: putstatic     #11                 // Field staticField:Ljava/lang/String;

//对应Java源文件代码
public static String staticField = "静态变量";
3-2 成员变量的初始化

成员变量field的初始化

如下指令用来将成员变量field的初始化。

 4: aload_0
 5: ldc           #2                  // String ==普通变量==
 7: putfield      #3                  // Field field:Ljava/lang/String;
 
//对应Java源文件代码
 public String field = "普通变量";
3-3 静态方法的调用
 3: aload_1
 4: invokestatic  #3                  // Method greeting:(Ljava/lang/String;)V
 
 //对应Java源码
 greeting(name);
3-4 打印成员变量值

如下指令用来执行代码块中第一行代码:打印成员变量field。

10: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_0
14: getfield      #3                  // Field field:Ljava/lang/String;
17: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V

//对应Java源文件代码
{
  System.out.println( field );
  ...
}

4 局部变量表

局部变量表用来存储字节码指令中参数和局部变量。在指令的操作过程中,我们会将局部变量表中的值作为参数写入操作数栈中,也会将操作数栈中计算的结果回写局部变量表中

从局部变量0中装载int类型值入栈
iload_0

//将栈顶引用类型值保存到局部变量0中。
astroe_0

5 Java字节码指令收集大全

Java字节码指令收集大全

上一篇 下一篇

猜你喜欢

热点阅读