类文件中的Java条件(字节码级别)
我正在玩一些Java类文件和字节码。但我坚持在类文件中的条件。 理论上,我理解这个概念,但我不理解类文件中的分支是如何完成的。下面是一个小例子:类文件中的Java条件(字节码级别),java,branch,bytecode,.class-file,conditional,Java,Branch,Bytecode,.class File,Conditional,我正在玩一些Java类文件和字节码。但我坚持在类文件中的条件。 理论上,我理解这个概念,但我不理解类文件中的分支是如何完成的。下面是一个小例子: public static void main(String[] args) { int a = 78; int b = 52; boolean c; if(a==b){ c = true; } else { c = false; } } 使用javap-c-verbose Equal.class,出现了以下
public static void main(String[] args) {
int a = 78;
int b = 52;
boolean c;
if(a==b){
c = true;
} else {
c = false;
}
}
使用javap-c-verbose Equal.class,出现了以下列表:
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=1
0: bipush 78
2: istore_1
3: bipush 52
5: istore_2
6: iload_1
7: iload_2
8: if_icmpne 16
11: iconst_1
12: istore_3
13: goto 18
16: iconst_0
17: istore_3
18: return
LineNumberTable:
line 4: 0
line 5: 3
line 7: 6
line 8: 11
line 10: 16
line 11: 18
StackMapTable: number_of_entries = 2
frame_type = 253 /* append */
offset_delta = 16
locals = [ int, int ]
frame_type = 252 /* append */
offset_delta = 1
locals = [ int ]
现在我在类文件中查找分支。如果icmpne为0xA0,则操作码的十六进制表示形式为0xA0。我假设分支标记将跟随0xA0。在我的例子中,有2个字节:0x0008。
我的问题:两个字节(0x0008)代表什么?
我试了很多。例如,我沿着LineNumberTable和Constant Pool的路径,但是找不到任何有意义的东西
(后藤当然也一样)
此外,以下是上述postet列表的完整序列:
10 4E // bipush 78
3C // istore_1
10 34 // bipush 52
3D // istore_2
1B // iload_1
1C // iload_2
A0 // if_icmpne
00 08 // ???
04 // iconst_1
3E // istore_3
A7 // goto
00 05 // ???
03 // iconst_0
3E // istore_3
B1 // return
提前谢谢你 0x0008是分支偏移量-即从当前指令向前跳转以查找下一条指令的字节数。因此,从
if_icmpne
跳8个字节(->00->08->04->3E->A7->00->05->03)到iconst_0
。同样的goto
:从goto
跳转5个字节(->00->05->03->3E->B1)到返回
,哦,我的天啊,真的很简单xD非常感谢你让我睁开了眼睛!这个问题的另一个问题。您可能知道如何生成这些“跳转”字节吗?因为在生成第一个if_icmpne时,需要知道从何处跳转。@ksascha您基本上必须在两次过程中完成,至少是向前跳转。因此,我必须在if_icmpne之后计算字节数,并在if_icmpne之后的第二步中写入这些字节数?是的,在第一次过程中,您将只保留2个字节,继续生成代码,然后计算从跳转位置到跳转目标的字节数,并将它们放入这两个字节中。