java字节码-无ipush指令
作为我学校项目的一部分,我需要深入研究java字节码。我开始编写简单的程序,并使用java字节码-无ipush指令,java,jvm,bytecode,Java,Jvm,Bytecode,作为我学校项目的一部分,我需要深入研究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
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
}
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
}
公共类主
源文件:“Main.java”
次要版本:0
主要版本:51
旗帜:ACC_公共、ACC_超级
固定池:
#1=Methodref#3.#12//java/lang/Object.“:()V
#2=类#13//Main
#3=类#14//java/lang/Object
#4=Utf8
#5=Utf8()V
#6=Utf8代码
#7=Utf8行号表
#8=Utf8主
#9=Utf8([Ljava/lang/String;)V
#10=Utf8源文件
#11=Utf8 Main.java
#12=名称和类型#4:#5/“”:()V
#13=Utf8主
#14=Utf8 java/lang/Object
{
公用干管();
旗帜:ACC_PUBLIC
代码:
堆栈=1,局部变量=1,参数大小=1
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
LineNumberTable:
第1行:0
公共静态void main(java.lang.String[]);
标志:ACC_公共,ACC_静态
代码:
堆栈=2,局部变量=2,参数大小=1
0:iconst_5
1:istore_1
2:iload_1
3:sipush 32765
6:iadd
7:istore_1
8:返回
LineNumberTable:
第4行:0
第5行:2
第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 #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
}
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
}
公共类主
源文件:“Main.java”
次要版本:0
主要版本:51
旗帜:ACC_公共、ACC_超级
固定池:
#1=Methodref#4.#13//java/lang/Object.“:()V
#2=整数32769
#3=等级#14//Main
#4=类#15//java/lang/Object
#5=Utf8
#6=Utf8()V
#7=Utf8代码
#8=Utf8行号表
#9=Utf8主
#10=Utf8([Ljava/lang/String;)V
#11=Utf8源文件
#12=Utf8 Main.java
#13=名称和类型#5:#6/“”:()V
#14=Utf8主
#15=Utf8 java/lang/Object
{
公用干管();
旗帜:ACC_PUBLIC
代码:
堆栈=1,局部变量=1,参数大小=1
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
LineNumberTable:
第1行:0
公共静态void main(java.lang.String[]);
标志:ACC_公共,ACC_静态
代码:
堆栈=2,局部变量=2,参数大小=1
0:iconst_5
1:istore_1
2:iload_1
3:ldc#2//int 32769
5:iadd
6:istore_1
7:返回
LineNumberTable:
第4行:0
第5行:2
第6行:7
}
所以现在数字存储在常量池中。我知道没有指令
ipush
,我可以用它将整数常量推送到堆栈中,但我想知道为什么没有这样的指令?基于简单的CISC设计,他们试图使每条指令尽可能短(以字节为单位)使用32位或64位常量的指令更容易/更短地引用常量表。这是由于字节码指令大小的一般限制。int不能放在一条指令中。@Marko这不是真的。有任意长的指令(tableswitch,lookupswitch)。真正的原因是,如果您必须指定整个int,您也可以将其保留在常量池中。