code bytecode java - aucune instruction ipush


Dans le cadre d'un de mes projets scolaires, j'ai besoin de creuser dans le bytecode java. J'ai commencé à écrire des programmes simples et à utiliser l'utilitaire javap pour afficher le bytecode généré et j'ai une question concernant les instructions *ipush.

Quand je vois le bytecode de ce code:

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

Je reçois

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
}

Et quand j'échange 32765 pour 32769 qui n'est pas dans la plage de court, j'obtiens

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
}

Donc maintenant le nombre est stocké dans le pool constant. Je sais qu'il n'y a pas d'instruction ipush que je pourrais utiliser pour pousser la constante entière à empiler, mais je me demande pourquoi il n'y a pas une telle instruction?

Author: Andna, 2013-06-02

1 answers

Basé sur une conception simple du CISC, ils ont essayé de rendre chaque instruction aussi courte que possible (en octets) Les instructions qui utilisent des constantes 32 bits ou 64 bits sont plus faciles/plus courtes pour se référer à une table constante.

 3
Author: Peter Lawrey, 2013-06-02 10:35:08