我有以下Java代码:
public static void fun(int[] a) {
int min;
for(int j=0;j<a.length-1;j++) {
min=j;
for(int i=j+1;i<a.length;i++)
if(a[i]<a[min]) min=i;
if(min!=j) {
int temp = a[j];
a[j] = a[min];
a[min]=temp;
}
}
}
我在上面的代码生成的类文件上使用了javap -c
来打印上面程序的Java字节码,我得到了下面的输出:
0: iconst_0 1: istore_2 2: iload_2 3: aload_0 4:芳纶 5: iconst_1 6: isub 7: if_icmpge 64 10: iload_2 11: istore_1 12: iload_2 13: iconst_1 14: iadd 15: istore_3 16: iload_3 17: aload_0 18:芳纶 19: if_icmpge 39 22: aload_0 23: iload_3 24: iaload 25: aload_0 26: iload_1 27: iaload 28: if_icmpge 33 31: iload_3 32: istore_1 33: iinc 3,1 36: goto 16 39: iload_1 40: iload_2 41: if_icmpeq 58 44: aload_0 45: iload_2 46: iaload 47: istore_3 48: aload_0 49: iload_2 50: aload_0 51: iload_1 52: iaload 53:最近 54: aload_0 55: iload_1 56: iload_3 57:中东 58: iinc 2,1 61: goto 2 64:返回
我的问题主要涉及istore
命令。如您所见,在"1:“处生成的字节码是istore_2
。在这种情况下,为什么使用istore_2
而不是istore_0
或istore_1
?正如我们稍后所看到的,在"11:“中,使用了istore_1
,但是istore_0
没有使用。这是否有原因,为什么变量2在开始使用,变量1在以后使用?
很抱歉,如果上面的措辞很糟糕,我现在才刚刚开始在大学学习Java字节码。
此外,我还试图从我们必须学习使用的列表中找出哪些命令使用多个字节。这是一个列表,有人能验证下命令中的“字节用法”(我不确定正确的术语)是否正确(我们必须在考试中手动转换,使用下面给出的命令列表,我需要知道每个命令使用了多少字节-在我们的讲座中解释得非常糟糕,而且讲师没有在线注释)。
"aload_n“-1字节 "iconst_n“-1字节 "iaload"- 1字节 "istore_n"- 1字节 "arraylength"- 1字节 "if_icmpge"- 3个字节 "if_icmple"- 3个字节 "iinc i“-不确定?3个字节? "goto n“-3个字节? “我返回”-1字节
最后,我相信goto n
使用3个字节(如上面所述),但是,有人能解释一下为什么会这样吗?
非常感谢你的帮助,我意识到这是一个很长的问题!劳伦
发布于 2016-01-01 11:16:13
关于字节的使用,您可以参考规格说明。引用开头的注释:“指令格式图中的每个单元格表示单个8位字节”,因此应该很容易获得每条指令的大小。
如您所见,在"1:“处生成的字节码是"istore_2”。在这种情况下,为什么使用"istore_2“而不是"istore_0”或"istore_1"?
仅仅因为在第1行,字节码将值为零存储到局部变量j
(恰巧在索引2处)。类似地,istore_1
将操作数堆栈上的值存储到索引1处的局部变量(在本例中为min
)。
这是因为,长话短说,每个方法都分配了一个包含局部变量的堆栈帧,可以通过编译时分配的索引访问。
对于goto
指令,这也在规格说明中
转到 branchbyte1 branchbyte2 无符号字节branchbyte1和branchbyte2用于构造带符号的16位分支偏移量,其中分支偏移量为(branchbyte1 << 8) _\_\从这个goto指令的操作码地址开始执行该偏移量。目标地址必须是包含此goto指令的方法中指令的操作码的地址。
操作码后有两个字节,构成16位偏移量.生成的目标地址计算如下:
target_address = address_of_current_goto + 16_bit_offset
https://stackoverflow.com/questions/34559067
复制相似问题