Java字节码初学者问题:“顺序”;“历史档案”;“可变用途”;字节用法“;等
我有以下Java代码:Java字节码初学者问题:“顺序”;“历史档案”;“可变用途”;字节用法“;等,java,bytecode,Java,Bytecode,我有以下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];
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;
}
}
}
publicstaticvoidfun(int[]a){
int-min;
对于(int j=0;j关于字节用法,您可以参考开头注释中的.Quoting:“指令格式图中的每个单元代表一个8位字节”,因此应该很容易获得每条指令的大小
如您所见,在“1:”处,生成的字节码是“istore_2”。在这种情况下,为什么使用“istore_2”,而不是“istore_0”或“istore_1”
仅仅是因为在第1行,字节码将零值存储到本地变量j
,该变量恰好位于索引2。类似地istore\u 1
将操作数堆栈上的值存储到索引1处的本地变量(在本例中,min
)
这是因为,长话短说,每个方法都分配了一个堆栈框架,其中包含一个可由编译时指定的索引访问的堆栈框架
对于goto
指令,它也位于:
后藤
分支细胞1
分支细胞2
无符号字节branchbyte1和branchbyte2用于构造有符号16位branchoffset,其中branchoffset为(branchbyte1“我需要了解每个命令使用多少字节”,-我对不得不掌握这样一项无用的技能表示哀悼。无论如何,有一个很好的命令列表可以很好地解释这个主题。谢谢你,也谢谢你的哀悼!这是什么类?这几乎只有在你编写Java编译器时才有用。无论如何,你可以找到JVM规范中的所有内容。Language设计和编译器为什么索引2在第1行到第1行使用?为什么索引0不在第1行使用,因为这是局部变量存储的第一个实例?谢谢你的帮助!编辑:另外,我仍然不明白为什么goto需要三个字节。我可以看出,有一个用于命令,另一个用于给定的分支编号呃,这个命令,但是,第三个字节做了什么,goto做了什么?@LaurenHayes编译器将参数a
翻译成一个LV,并将其放在索引0的表中,然后将min
翻译成索引1的LV,依此类推(考虑到程序代码的顺序,这是有意义的)。然后,第一条指令处理j
(在索引2中赋值)。哦,等等,所以编译器基本上是“赋值”(或“搁置”)索引1处的LV到min
,但还没有对它做任何处理,因为它没有初始化,然后在for循环声明中为j
变量在LV 2中存储0,然后在min
的LV到1处存储值。编辑:另外,关于goto
,我知道它在规范中,h不过,我不明白它在做什么,branchbyte1
和branchbyte2
是什么,以及goto
在用它们做什么。你能详细说明一下吗?非常感谢你的帮助!@LaurenHayes是的。我认为局部变量表的创建是一个独立的步骤,在生成ins之前发生指令。然后指令引用这些局部变量,并执行您所描述的。好的,这对我来说更有意义,非常感谢!