码迷,mamicode.com
首页 > 其他好文 > 详细

(十九)加载指令

时间:2018-05-21 00:57:14      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:compile   null   init   byte   top   style   icons   round   rbo   

一、概念 

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

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

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

 

(十九)加载指令

标签:compile   null   init   byte   top   style   icons   round   rbo   

原文地址:https://www.cnblogs.com/shyroke/p/9065274.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!