(十九)加载指令

Posted 专注改变人生。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(十九)加载指令相关的知识,希望对你有一定的参考价值。

一、概念 

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

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

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:\Users\Administrator\Desktop>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)的值并赋值给第1个局部变量result
  • 4: ldc 将常量(“admin”)压入到操作数栈中。
  • 6: astore 将操作数栈的值弹出,即(“admin”)赋值给c
  • 8: iconst_4 将常量(4,编译器优化,识别2和2都是常量后,会先进行加法操作)压入操作数栈中
  • 9: ireturn

 

以上是关于(十九)加载指令的主要内容,如果未能解决你的问题,请参考以下文章

这些角度电子邮件指令代码片段如何连接

Vue2.0学习—自定义指令(四十九)

如何在运行时加载的 jsp 中包含 html 片段?

十九dbms_resource_manager(用于维护资源计划,资源使用组和资源计划指令)

电子海图开发第十九篇 web电子海图 使用OpenLayers加载瓦片地图(共一百篇)

十九动态加载脚本和样式