• (十九)加载指令


    一、概念 

    加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输,这类指令包括如下内容。

    • 将一个局部变量加载到操作栈:

    iload、iload_<n>、lload、lload_<n>、fload、fload_<n>、dload、dload_<n>、aload、aload_<n>。

    • 将一个数值从操作数栈存储到局部变量表:

    istore、istore_<n>、lstore、lstore_<n>、fstore、fstore_<n>、dstore、dstore_<n>、astore、astore_<n>。

    • 将一个常量加载到操作数栈:

    bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconst_ml、iconst_<i>、lconst_<l>、fconst_<f>、dconst_<d>。

    • 扩充局部变量表的访问索引的指令:

    wide。

           上面所列举的指令的指令助记符中,有一部分是以尖括号结尾的(例如iload_<n>),这些指令助记符实际上是代表了一组指令(例如iload_<n>,他代表了iload_0、iload_1、iload_2和iload_3这几条指令)。这几组指令都是某个带有一个操作数的通用指令(例如iload)的特殊形式,对于这若干组特殊指令来说,他们省略掉了显示的操作数,不需要进行取操作数的动作,实际上操作数就隐含在指令中。除了这点之外,他们的语义与原生的通用指令完全一致(例如iload_0的语义与操作数为0时的iload指令语义完全一致)。这种指令表示方法在本书以及《Java虚拟机规范》中都是通用的。

    二、案例

    • 源码如下:
    public class Test {
    
        public int addNumber(int a,int b){
            
            int result = a + b;
            
            String c = "admin";
            
            return 2+2;
            
        }
    }
    • javap查看如下:
    C:UsersAdministratorDesktop>javap -verbose Test.class
    Classfile /C:/Users/Administrator/Desktop/Test.class
      Last modified 2018-5-20; size 269 bytes
      MD5 checksum e26c0d715552b3c00c071a044e16d7a9
      Compiled from "Test.java"
    public class Test
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #4.#13         // java/lang/Object."<init>":()V
       #2 = String             #14            // admin
       #3 = Class              #15            // Test
       #4 = Class              #16            // java/lang/Object
       #5 = Utf8               <init>
       #6 = Utf8               ()V
       #7 = Utf8               Code
       #8 = Utf8               LineNumberTable
       #9 = Utf8               addNumber
      #10 = Utf8               (II)I
      #11 = Utf8               SourceFile
      #12 = Utf8               Test.java
      #13 = NameAndType        #5:#6          // "<init>":()V
      #14 = Utf8               admin
      #15 = Utf8               Test
      #16 = Utf8               java/lang/Object
    {
      public Test();
        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 2: 0
    
      public int addNumber(int, int);
        descriptor: (II)I
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=5, args_size=3
             0: iload_1
             1: iload_2
             2: iadd
             3: istore_3
             4: ldc           #2                  // String admin
             6: astore        4
             8: iconst_4
             9: ireturn
          LineNumberTable:
            line 6: 0
            line 8: 4
            line 10: 8
    }
    SourceFile: "Test.java"
    • 如上代码金色标注,args_size=3,但是查看源码参数数量只有2个(int a, int b) ,其实会自动加一个this引用
    • 0: iload_1 表示将第一个局部变量(a)压入操作数栈中.
    • 1: iload_2表示将第二个局部变量(b)压入操作数栈中.
    • 2: iadd  执行add操作
    • 3:istore_3 将操作数栈的值弹出,即(a+b)的值并赋值给第3个局部变量result
    • 4: ldc 将常量(“admin”)压入到操作数栈中。
    • 6: astore 将操作数栈的值弹出,即(“admin”)赋值给c
    • 8: iconst_4 将常量(4,编译器优化,识别2和2都是常量后,会先进行加法操作)压入操作数栈中
    • 9: ireturn

     Tip: 当int取值-1~5采用iconst指令,取值-128~127采用bipush指令,取值-32768~32767采用sipush指令,取值-2147483648~2147483647采用 ldc 指令。

  • 相关阅读:
    Windows 下安装VMWare Linux后设置网络
    《Pentaho Reporting 3.5 for Java Developers 》
    CDF组件Table Component 交互实验
    【原创】提醒久坐器:一个小时提醒一次,让自己不要长时间坐在椅子上
    CDF学习(Community Dashboard Framework)
    pentaho BI server3.5 cdf tablecomponent
    pentaho汉化工作
    与CDF中的TableComponent组件交互 转自Pedro Alves on Business Intelligence
    Pentaho初学者的好书
    MDX语言中的Filter
  • 原文地址:https://www.cnblogs.com/shyroke/p/9065274.html
Copyright © 2020-2023  润新知