zoukankan      html  css  js  c++  java
  • 字节码指令以及操作数栈的分析

    事先创建一个java类,如下:

    package com.yang.jvm;
    
    public class Demo {
    
        public int getNum(){
            int a=1;
            int b=2;
            int c=3;
            int d=4;
            return (a+b-c)*d;
        }
    }

    在命令窗口输入:F:jvmdemo>javap -c -verbose build/classes/java/main/com/yang/jvm/Demo.class
    
    

    执行命令后获得字节码文件内容:

    Classfile /F:/jvmdemo/build/classes/java/main/com/yang/jvm/Demo.class
      Last modified 2019-10-23; size 428 bytes
      MD5 checksum b4f01d8c01f685e501ee4f8dc209652d
      Compiled from "Demo.java"
    public class com.yang.jvm.Demo
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #3.#20         // java/lang/Object."<init>":()V
       #2 = Class              #21            // com/yang/jvm/Demo
       #3 = Class              #22            // java/lang/Object
       #4 = Utf8               <init>
       #5 = Utf8               ()V
       #6 = Utf8               Code
       #7 = Utf8               LineNumberTable
       #8 = Utf8               LocalVariableTable
       #9 = Utf8               this
      #10 = Utf8               Lcom/yang/jvm/Demo;
      #11 = Utf8               getNum
      #12 = Utf8               ()I
      #13 = Utf8               a
      #14 = Utf8               I
      #15 = Utf8               b
      #16 = Utf8               c
      #17 = Utf8               d
      #18 = Utf8               SourceFile
      #19 = Utf8               Demo.java
      #20 = NameAndType        #4:#5          // "<init>":()V
      #21 = Utf8               com/yang/jvm/Demo
      #22 = Utf8               java/lang/Object
    {
      public com.yang.jvm.Demo();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 3: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Lcom/yang/jvm/Demo;
    
      public int getNum();
        descriptor: ()I
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=5, args_size=1
             0: iconst_1
             1: istore_1
             2: iconst_2
             3: istore_2
             4: iconst_3
             5: istore_3
             6: iconst_4
             7: istore        4
             9: iload_1
            10: iload_2
            11: iadd
            12: iload_3
            13: isub
            14: iload         4
            16: imul
            17: ireturn
          LineNumberTable:
            line 6: 0
            line 7: 2
            line 8: 4
            line 9: 6
            line 10: 9
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      18     0  this   Lcom/yang/jvm/Demo;
                2      16     1     a   I
                4      14     2     b   I
                6      12     3     c   I
                9       9     4     d   I
    }
    SourceFile: "Demo.java"
    
    F:jvmdemo>javap -c -verbose build/classes/java/main/com/yang/jvm/Demo.class
    Classfile /F:/jvmdemo/build/classes/java/main/com/yang/jvm/Demo.class
      Last modified 2019-10-23; size 428 bytes
      MD5 checksum b4f01d8c01f685e501ee4f8dc209652d
      Compiled from "Demo.java"
    public class com.yang.jvm.Demo
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #3.#20         // java/lang/Object."<init>":()V
       #2 = Class              #21            // com/yang/jvm/Demo
       #3 = Class              #22            // java/lang/Object
       #4 = Utf8               <init>
       #5 = Utf8               ()V
       #6 = Utf8               Code
       #7 = Utf8               LineNumberTable
       #8 = Utf8               LocalVariableTable
       #9 = Utf8               this
      #10 = Utf8               Lcom/yang/jvm/Demo;
      #11 = Utf8               getNum
      #12 = Utf8               ()I
      #13 = Utf8               a
      #14 = Utf8               I
      #15 = Utf8               b
      #16 = Utf8               c
      #17 = Utf8               d
      #18 = Utf8               SourceFile
      #19 = Utf8               Demo.java
      #20 = NameAndType        #4:#5          // "<init>":()V
      #21 = Utf8               com/yang/jvm/Demo
      #22 = Utf8               java/lang/Object
    {
      public com.yang.jvm.Demo();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 3: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0       5     0  this   Lcom/yang/jvm/Demo;
    
      public int getNum();
        descriptor: ()I
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=5, args_size=1
             0: iconst_1
             1: istore_1
             2: iconst_2
             3: istore_2
             4: iconst_3
             5: istore_3
             6: iconst_4
             7: istore        4
             9: iload_1
            10: iload_2
            11: iadd
            12: iload_3
            13: isub
            14: iload         4
            16: imul
            17: ireturn
          LineNumberTable:
            line 6: 0
            line 7: 2
            line 8: 4
            line 9: 6
            line 10: 9
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      18     0  this   Lcom/yang/jvm/Demo;
                2      16     1     a   I
                4      14     2     b   I
                6      12     3     c   I
                9       9     4     d   I
    }
    SourceFile: "Demo.java"
    

     本次需要分析的字节码内容如下:

     java虚拟机栈和栈帧关系图:

    栈帧的组成:局部变量表,操作数栈,动态链接,方法出口 

    由字节码文件可以看到,栈深度为2(stack=2)说明操作数栈的深度是2,本地变量表变量长度为5因此过程分析如下:

    0.指令 iconst_1 意义:将常量1压入操作数栈的栈顶

     1.指令istore_1:意义将操作数栈顶的数字弹出,然后赋值给局部变量表索引为1的变量,索引为0的变量为this

     
    将常量1入栈,并存到栈顶

     

     

     2. 同理 iconst_2istore_2 分别表示将常量2入栈,存到栈顶,然后出栈,赋值给局部变量表索引为2的变量


     3.之后的指令 iconst_3 和 istore_3 , iconst_4 和 istore 4 同理,他们执行完后此时操作数栈和局部变量表如下:

     4. 之后执行 iload_1,意义是将局部变量表索引为1的变量压入操作数栈的栈顶
      

     5.同理:iload_2,意义是将局部变量表索引为2的变量压入操作数栈的栈顶此时:

     6.指令iadd,表示将操作数栈的2个值弹出,然后计算他们的和,之后将结果压入栈顶

     此时:

     7.之后执行命令iload_3,表示将局部变量索引为3的变量入栈,到栈顶,此时:

     8.isub将操作数栈的2个数弹出,然后做减法,之后将结果压入栈顶

     9. iload 4 表示将局部变量索引为4的变量压入栈顶:此时

    10. imul 表示将操作数栈的2个数弹出,并做乘法运算,之后将结果压入栈顶:

     11.ireturn指令:将操作数栈顶的数弹出,然后压入调用者的操作数栈的栈顶,如果操作操作数栈除了栈顶的内容外还有其他内容,其他内容都会被丢弃掉,所以这里将0返回



         


           

  • 相关阅读:
    UVA12206 Stammering Aliens 【SAM 或 二分 + hash】
    字符串hash
    BZOJ1064 [Noi2008]假面舞会 【dfs】
    BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】
    BZOJ1499 [NOI2005]瑰丽华尔兹 【单调队列优化dp】
    BZOJ3343 & 洛谷2801:教主的魔法——题解
    BZOJ2821:作诗——题解
    BZOJ2724:[Violet 6]蒲公英——题解
    BZOJ2653:middle——题解
    BZOJ2588:Count on a tree——题解
  • 原文地址:https://www.cnblogs.com/yangxiaohui227/p/11724828.html
Copyright © 2011-2022 走看看