【问题标题】:java bytecode - no ipush instructionjava字节码 - 没有ipush指令
【发布时间】:2013-06-02 10:10:47
【问题描述】:

作为我学校项目之一的一部分,我需要深入研究 Java 字节码。我开始编写简单的程序并使用javap 实用程序查看生成的字节码,我有一个关于*ipush 指令的问题。

当我查看这段代码的字节码时:

public class Main{
  public static void main(String []args){
    int a;
    a=5;
    a=a+32765;
  }
}

我来了

public class Main
  SourceFile: "Main.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
  #1 = Methodref          #3.#12         //  java/lang/Object."<init>":()V
  #2 = Class              #13            //  Main
  #3 = Class              #14            //  java/lang/Object
  #4 = Utf8               <init>
  #5 = Utf8               ()V
  #6 = Utf8               Code
  #7 = Utf8               LineNumberTable
  #8 = Utf8               main
  #9 = Utf8               ([Ljava/lang/String;)V
  #10 = Utf8               SourceFile
  #11 = Utf8               Main.java
  #12 = NameAndType        #4:#5          //  "<init>":()V
  #13 = Utf8               Main
  #14 = Utf8               java/lang/Object
{
  public Main();
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 1: 0

  public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
  stack=2, locals=2, args_size=1
    0: iconst_5      
    1: istore_1      
    2: iload_1       
    3: sipush        32765
    6: iadd          
    7: istore_1      
    8: return        
  LineNumberTable:
    line 4: 0
    line 5: 2
    line 6: 8
}

当我将 32765 换成不在短期范围内的 32769 时,我得到了

public class Main
  SourceFile: "Main.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
  #1 = Methodref          #4.#13         //  java/lang/Object."<init>":()V
  #2 = Integer            32769
  #3 = Class              #14            //  Main
  #4 = Class              #15            //  java/lang/Object
  #5 = Utf8               <init>
  #6 = Utf8               ()V
  #7 = Utf8               Code
  #8 = Utf8               LineNumberTable
  #9 = Utf8               main
  #10 = Utf8               ([Ljava/lang/String;)V
  #11 = Utf8               SourceFile
  #12 = Utf8               Main.java
  #13 = NameAndType        #5:#6          //  "<init>":()V
  #14 = Utf8               Main
  #15 = Utf8               java/lang/Object
{
  public Main();
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 1: 0

  public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
  stack=2, locals=2, args_size=1
    0: iconst_5      
    1: istore_1      
    2: iload_1       
    3: ldc           #2                  // int 32769
    5: iadd          
    6: istore_1      
    7: return        
  LineNumberTable:
    line 4: 0
    line 5: 2
    line 6: 7
}

所以现在这个数字存储在常量池中。我知道没有指令ipush 可以用来将整数常量推入堆栈,但我想知道为什么没有这样的指令?

【问题讨论】:

  • 这是由于对字节码指令大小的一般限制。 int 不适合一条指令。
  • @Marko 这不是真的。有任意长指令(tableswitch、lookupswitch)。真正的原因是,如果你必须指定整个 int,你还不如把它放在常量池中。

标签: java jvm bytecode


【解决方案1】:

基于简单的 CISC 设计,他们试图使每条指令尽可能短(以字节为单位)使用 32 位或 64 位常量的指令更容易/更短地引用常量表。

【讨论】:

    猜你喜欢
    • 2014-05-05
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多