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?
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.