首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java字节码初学者的问题:"istore“变量使用顺序、”字节用法“等

Java字节码初学者的问题:"istore“变量使用顺序、”字节用法“等
EN

Stack Overflow用户
提问于 2016-01-01 19:00:22
回答 1查看 1.1K关注 0票数 3

我有以下Java代码:

代码语言:javascript
运行
复制
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_0istore_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个字节(如上面所述),但是,有人能解释一下为什么会这样吗?

非常感谢你的帮助,我意识到这是一个很长的问题!劳伦

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-01 19: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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34559067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档