美文网首页
Java虚拟机-字节码指令

Java虚拟机-字节码指令

作者: 贪睡的企鹅 | 来源:发表于2019-08-04 16:46 被阅读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 = "静态变量";
  • 1 ldc:ldc指令用来将常量池中指定的常量放入操作数栈中,这里指定的常量是#10,常量类型是String,其值#41指向一个类型为utf-8的常量,对应值为"静态变量"

  • 2 putstatic:putstatic指令用来将操作数栈顶的元素(1步骤入栈元素)赋值给指定静态变量,并将栈顶元素从操作数栈中出栈。这里指定静态变量用常量池中第#11常量来表示,该常量类型是一个字段的符号引用。这里用来对类staticField静态变量初始化。

3-2 成员变量的初始化

成员变量field的初始化

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

 4: aload_0
 5: ldc           #2                  // String ==普通变量==
 7: putfield      #3                  // Field field:Ljava/lang/String;
 
//对应Java源文件代码
 public String field = "普通变量";
  • 1 aload_0:将局部变量表中第一个局部变量的引用推到栈顶。在Java虚拟机中对于非静态方法调用,会将当前对象引用放入到局部变量表中第一个局部变量位置。【调用方法指令前,需要将调用方法的对象加入到操作数栈中。此步骤是调用构造函数的一个中间步骤】

  • 2 ldc:将常量池中#2常量引用推入操作数栈。该常量是一个String类型的常量,其值#32指向utf-8字面量对应为字符串"==普通变量=="。

  • 3 putfield:putfield指令用来将操作数栈顶的元素(2步骤入栈元素)赋值给指定成员变量,并从操作数栈中出栈。同时将新的栈顶元素(1步骤入栈元素)作为赋值成员变量所在的对象,并从操作数栈中出栈。这里指定成员变量用常量池中第#2常量来表示,该常量类型是一个字段的符号引用。这里获取的是类对象中field成员变量。

3-3 静态方法的调用
 3: aload_1
 4: invokestatic  #3                  // Method greeting:(Ljava/lang/String;)V
 
 //对应Java源码
 greeting(name);
  • 1 aload_1:aload_1指令用来将局部变量表下标为1的元素的值推到操作数栈栈顶【这里是为了给下一步做参数】

  • 2 invokestatic指令用来调用类中静态方法。如果调用的静态方法描述中需要传入参数,则会将当前操作数栈顶元素作为方法的参数,并从操作数中出栈,静态方法执行完毕会将返回值推到操作数栈中。静态方法用常量池中常量来表示,该常量类型是一个方法的符号引用。这里含义是调用类中静态方法greeting。greeting有一个参数,此时会将栈顶的元素(1步骤入栈元素)作为参数,其值指向指向常量池中类型为UTF-8的常量,值为“Louis”,并从操作数中出栈。由于println方法不存在返回值,因而不存在入栈操作。

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 );
  ...
}
  • 1 getstatic:getstatic指令用来表示获取一个类的静态变量引用,并将其引用推到操作数栈中。指令获取静态变量用常量池中第#4常量来表示,该常量类型是一个字段的符号引用。这里获取的是System类中PrintStream字段引用放入栈中。

  • 2 aload_0:将局部变量表中第一个局部变量的引用推到栈顶。在Java虚拟机中对于非静态方法调用,会将当前对象引用放入到局部变量表中第一个局部变量位置。【调用方法指令前,需要将调用方法的对象加入到操作数栈中。此步骤是调用构造函数的一个中间步骤】

  • 3 getfield:getfield指令用来获取栈顶元素(2步骤入栈元素)的指定成员变量,在此会将栈顶元素(2步骤入栈元素)出栈,并将获取成员变量入栈。这里指定成员变量用常量池中第#3常量来表示,该常量类型是一个字段的符号引用。这里用来获取当前对象this.field成员变量,将this对象出栈,将成员变量入栈。

  • 4 invokevirtual:invokespecial指令用来调用超类构造方法,实例初始化方法<init>,私有方法。和invokespecial不同的是invokespecial指令支持动态链接。如果调用的方法描述中需要传入参数,则会将当前操作数栈顶元素作为方法的参数,并从操作数中出栈。当参数出栈完毕或方法不需要传入参数,会将当前栈顶元素作为方法调用的对象,并从操作数栈中出栈。调用的具体方法用常量池中第#5常量来表示,该常量类型是一个方法的符号引用。方法执行完毕会将返回值推到操作数栈中。这里含义是调用PrintStream对象println方法,由于方法中存在一个参数,此时会将栈顶的元素(3步骤入栈元素)作为参数,其值指向对象field成员变量引用,并从操作数中出栈,接着将新的栈顶元素作为方法调用对象(1步骤入栈元素),并从操作数中出栈。由于println方法不存在返回值,因而不存在入栈操作。

4 局部变量表

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

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

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

5 Java字节码指令收集大全

Java字节码指令收集大全

相关文章

  • Java ByteCode

    什么是Java字节码指令?简而言之,Java字节码指令就是Java虚拟机能够听得懂、可执行的指令,可以说是Jvm层...

  • Java字节码

    参考链接:一文让你明白Java字节码 Java字节码 Java虚拟机字节码指令 Java号称是一门“一次编译到处运...

  • Android字节码插桩demo

    1. 基本概念 1.1 java字节码 Java字节码是Java虚拟机执行的一种虚拟指令格式。可通过javac 编...

  • Java字节码解读

    1. 字节码 Java字节码是Java虚拟机执行的一种指令格式.class文件是编译器编译之后供虚拟机解释执行的二...

  • Java虚拟机知识点【字节码】

    字节码指令   Java虚拟机的字节码指令由一个字节长度,代表着某种特定操作含义的操作码以及跟随其后的零至多个代表...

  • 28-字节码指令

    一、概述 Java字节码对于虚拟机,就好像汇编语言对于计算机,属于基本执行指令 Java虚拟机的指令由“一个字节长...

  • 字节码指令集的概述

    Java字节码对于虚拟机,就好像汇编语言对于计算机,属于基本执行指令。 Java虚拟机的指令由一个字节长度的、代表...

  • 字节码指令

    描述 本文摘自深入理解Java虚拟机中关于字节码的介绍,部分指令参考,oracle字节码指令集。 数据类型:byt...

  • Java虚拟机-字节码指令

    字节码指令 Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随...

  • JVM深入理解(二)

    JVM相关知识详解 一、Java虚拟机指令集 Java虚拟机指令由一个字节长度的、代表某种特定含义的操作码(Opc...

网友评论

      本文标题:Java虚拟机-字节码指令

      本文链接:https://www.haomeiwen.com/subject/iieydctx.html