我正在研究java字节码,当我注意到简单表达式Math.max(0,1)变成了下面的字节码指令。
ICONST_0,
ICONST_1,
INVOKESTATIC(java/lang/Math.max)
我的问题是,如果java使用倒数第一个堆栈,这意味着1现在将位于堆栈上的0前面,这意味着vm必须反转堆栈上项目的顺序调用max指令在1之前得到0。然而在规范中,它说明了这一点,我的假设是正确的。
答案 0 :(得分:6)
参数堆栈只是一个抽象。当一个操作接受n个参数时,前n个参数从堆栈中取出并从底部到顶部使用,正如您所观察到的那样。这不仅适用于invokestatic,也适用于每个字节码指令。
例如,以下序列
iconst_0 iconst_1 iconst_2 ISUB
将0,1和2推入堆栈。 isub指令弹出前两个值1和2,并从下到上使用它们,因此结果为1-2 = -1。因此,最终结果是包含0,-1的堆栈。
如果您对此类详细信息感兴趣,请尝试阅读JVM规范。
答案 1 :(得分:1)
如果java使用后进先出堆栈
还有另一种吗?
这意味着当vm调用max指令获取0之前的0时,vm必须反转堆栈中项目的顺序
不,不。零已经在“之前”。 任何方法的参数按照它们在源文本中出现的顺序推送,实际上是局部变量声明。我不知道为什么你认为需要任何逆转。事实并非如此。