【问题标题】:When can I get pop2 opcode in a .class file compiled from Java source code?什么时候可以在从 Java 源代码编译的 .class 文件中获取 pop2 操作码?
【发布时间】:2018-04-25 03:12:37
【问题描述】:

我目前正在开发 Java 反编译器。

我阅读了 JVM 规范,我知道pop2 可以操作一个堆栈值(类别 2 值)或两个堆栈值(其他类别值)。

我只想知道pop2 的两个堆栈值操作何时会发生?谁能给我看一些Java源代码,其编译结果包含两个堆栈值操作pop2

【问题讨论】:

  • pop2(或 JVM 中的任何指令)仅在 one 堆栈上运行。也许您的意思是“堆栈值”(JVM 堆栈中的术语)。您的问题目前的编写方式没有多大意义。在任何情况下,pop2 都会弹出 2 个类别 1 的值(每个类别 1 的值是 32 位,因此它会从堆栈中弹出 64 位)。或者它弹出 1 个类别 2 值(每个类别 2 值是 64 位,因此它再次从堆栈中弹出 64 位)。 pop2 只是从堆栈中弹出 64 位或 8 个字节。
  • @ErwinBolwidt 对不起,我的意思是“堆栈值”。我已经更正了我的问题。
  • @ErwinBolwidt 我认为 Stephen C 给了我一个合理的答案。

标签: java bytecode decompiler


【解决方案1】:

如果你弹出一个double或long,POP2肯定会被调用,例如

thisMethodReturnsALong(); thisMethodReturnsADouble();

在其他情况下。

【讨论】:

  • 感谢您的回答,但我已经提到我知道pop2 可以弹出一个 2 类堆栈值的情况(我已经更正了我的问题:我应该说“堆栈值”而不是“堆栈”)。希望看到pop2弹出两个1类堆栈值的Java代码示例。
【解决方案2】:

根据我对 Java 8 中 javac 编译器源代码的简要阅读,没有地方它会发出 POP2 以从堆。如果需要弹出两个 category-1 值,则编译器将发出两个 POP 字节码。

注意事项:

  • 我只看了一个版本的 OpenJDK javac 编译器
  • 还有其他(非 Sun/Oracle)Java 字节码编译器
  • 字节码可以通过其他方式生成或修改......包括代码混淆器!

POP2 的二值弹出行为似乎在 JIT 编译器出现之前的早期 Java 字节码编译器中使用过。但现在我们有了 JIT 编译器,字节码编译器将两个 POP 字节码“优化”为一个 POP2没有意义

【讨论】:

  • 感谢您的回答。这也是我的猜测。我不懂 C++,也没有尝试阅读 javac 源代码。我尝试构建一些 java 程序,而对于这些程序,编译器从未将两个 pop 优化为一个 pop2。我还发现一些带有pop2 的字节码会弹出两个类别1 的值,但它们都不是由Java 源代码中的javac 生成的。
  • javac 编译器是用 Java 编写的。没有借口:-)
  • 我应该更勇敢!但是,我正在尝试通过编写 Java 反编译器来学习 Java。我实际上在使用 Scala :-)。
  • @JiannLan 我不认为“尝试通过编写 Java 反编译器来学习 Java”是一种可行的策略。除此之外,我不明白你的问题的目的。您必须处理 pop2 指令的方式是直截了当的,那么为什么您认为编译器是否实际使用它很重要?
  • @Holger “尝试通过编写 Java 反编译器来学习 Java”是我的目的之一,而不是整个项目的主要目的。我不在乎这是否是可行的策略。 “编译器如何实际使用它”是我个人的好奇——当我描述我的问题的背景时,我认为有太多个人兴趣的东西没有用。我问了一个问题,我认为这个问题的答案对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 2014-05-28
相关资源
最近更新 更多