当前位置: 首页 > 知识库问答 >
问题:

jvm中pop指令和pop2指令的区别是什么?

东方嘉佑
2023-03-14

我参考了下面的oracle jvm文档

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.pop

弹出操作弹出操作数堆栈顶部的值

总体安排

pop表格pop=87(0x57)

操作堆栈...,值→

...

说明从操作数堆栈中弹出顶部值。

除非值是1类计算类型的值(§2.11.1),否则不得使用pop指令。

Pop2操作弹出顶部的一个或两个操作数堆栈值

总体安排

pop2表格pop2=88(0x58)

操作数堆栈格式1:

...,值2,值1→

...

其中,value1和value2均为1类计算类型的值(§2.11.1)。

表格2:

..., 价值→

...

其中值是第2类计算类型的值(§2.11.1)。

说明从操作数堆栈中弹出顶部的一个或两个值。

“从操作数堆栈中弹出顶部的一个或两个值”是什么意思?使用pop2时会有什么例子?

共有3个答案

杜砚
2023-03-14

弹出:从堆栈中弹出最上面的单字项并将其丢弃。

POP2:从堆栈中删除两个单字项(例如两个整数,或一个整数和一个对象引用)或一个双字项(即双倍或顺行)。

同样的javadoc提到的问题conatins下面的信息:

表2.3.Java虚拟机中的实际和计算类型

Actual type Computational type      Category


1. byte             int               1
2. char             int               1
3. short            int               1
4. int              int               1
5. float            float             1
6. reference        reference         1
7. returnAddress    returnAddress     1
8. boolean          int               1
9. long             long              2
10. double          double            2

正如你所见,只有long和double属于第二类。这是因为所有其他的都是计算32位,而long和double是64位。

下面的例子说明了这一点。

public class PopVsPop2 {

public static int popint(){

    return  1;
}

public static long poplong() {
    return 1;
}


public static Long popLong() {
    return 1L;
}

public static void main(String[] args) {    

    popint();
    poplong();
    popLong();
}

上面的javacode有以下生成的字节码:

public static main(String[]) : void
   L0
    LINENUMBER 24 L0
    INVOKESTATIC PopVsPop2.popint () : int
    POP
   L1
    LINENUMBER 25 L1
    INVOKESTATIC PopVsPop2.poplong () : long
    POP2
   L2
    LINENUMBER 26 L2
    INVOKESTATIC PopVsPop2.popLong () : Long
    POP
   L3
    LINENUMBER 27 L3
    RETURN
   L4
    LOCALVARIABLE args String[] L0 L4 0
    MAXSTACK = 2
    MAXLOCALS = 1

如你所见

popint()-POP-因为int属于第1类。

poplong()-POP2-因为long属于第2类。双倍也是一样。

popLong()-POP-因为这里Long指的是java.lang.Long,它是一个引用类型。因此是类别1。

洪和平
2023-03-14

“从操作数堆栈中弹出顶部的一个或两个值”是什么意思?

这样想1

>

  • POP字节码弹出一个值,该值占用堆栈上的一个x 32位单词。

    POP2字节码要么弹出一个占用两个x 32位字的值,要么弹出两个占用一个x 32位字的值。

    当使用POP2时,什么是示例?

    1. 弹出一个longdouble值;e、 g.丢弃方法调用产生的不需要的long结果,或
    2. 弹出两个int

    请注意,当前一代Oracle/OpenJDKjavac编译器不会向POP2发出POP2to POP2值。如果堆栈上有两个32位的值需要弹出,编译器将发出两条POP指令。所以,对于普通Java代码,我不能给出案例#2的例子。(但Java或其他语言的第三方编译器可能会使用它,或者人们用其他方式创建字节码。)

    我对JVM内部的了解还不够多,无法确定,但是有POP2的一个可能的原因是,如果您使用两个POP指令弹出(例如)一个long,那么在整个序列中,堆栈将处于无效状态。这很容易导致验证错误。

    1-这不是严格正确的。堆栈上的值不是严格意义上的32或64位。例如,64位机器上的引用或返回地址是64位...但是它仍然被建模为类别1值。对此的解释是字节码指令集最初被设计为在32位机器上解释。

  • 许远航
    2023-03-14

    编写一个包含主方法的java小程序

    System.currentTimeMillis();
    

    不要使用此通话的结果。然后字节码看起来像

    INVOKESTATIC java/lang/System.currentTimeMillis()J
    POP2
    

    系统。currentTimeMillis()在堆栈上放置一个长值(64位,宽)。然而,这个堆栈内容不再被使用,因此必须弹出它,以便可以访问其他堆栈内容。32位(正常大小)需要一个简单的POP,64位(宽大小)需要一个POP2

     类似资料:
    • 所以我和一位面试官(你的标准人力资源经理)谈了他们在面试中真正想要的东西,他提到了一些关于测试JVM指令知识的东西(以及其他很多东西)。 我不知道那是什么,但我以为他说的是字节码指令。 我做了一些研究,似乎在“JVM指令”上找不到任何东西,我只找到了字节码指令的引用,我已经知道了字节码指令。 例如:http://docs.oracle.com/javase/specs/jvms/se7/html/

    • 问题内容: 我已经仔细阅读了有关该主题的 AngularJS 文档,然后摆弄了一条指令。这是jsfiddle。 以下是一些相关的摘要: 从 HTML : 从窗格指令: 我没有几件事: 为什么必须与和一起使用? 我是否还可以直接访问父范围,而不用属性装饰元素? 该文档说: “通常希望通过表达式将数据从隔离的范围传递到父范围” ,但这似乎也可以与双向绑定一起使用。为什么表达途径会更好? 我发现了另一个

    • 我猜这是一个基本的问题,但是为什么没有sload指令呢?为什么你可以加载除了short之外的所有原语?(有saload,但仍然……) 对于:

    • 我仔细阅读了关于这个主题的AngularJS文档,然后随意修改了一个指令。小提琴在这里。 下面是一些相关的片段: > 来自HTML: 在窗格指令中: 有几件事我不明白: 为什么必须使用与和与? 是否也可以直接访问父范围,而不使用属性装饰元素? 文档说“通常希望通过表达式将数据从独立作用域传递到父作用域”,但这似乎也适用于双向绑定。为什么表达式路由会更好? 我找到了另一个显示表达式解的fiddle:

    • 我刚刚开始使用Angular 2。 我想知道Angular 2中的组件和指令有什么区别?