1

我正在尝试使用逻辑和符号“&&”执行 if 语句。这是我想要做的事情:asm 字节码中的 Μy 堆栈具有值 0 和 1,我想得到一个带有“逻辑和”的结果,在我们的例子中它不会进入 if 语句。

我已经尝试过 Opcodes.IFEQ 和 Opcodes.IFNE 指令,但不起作用。'||'也是如此 和 '!' 逻辑符号

有任何想法吗?

4

2 回答 2

3

&&和的字节码模式||

想想短路操作员喜欢什么&&||实际做了什么。你有一些条件分支。让我们考虑一下&&。您正在有效评估的是:

if (left)
    if (right) <do something>
endIf

没有单一的字节码指令可以描述这种行为。您需要一些标签和条件分支指令:

.start
    <left expression>
    IFEQ .endIf // if left evaluates to zero (false), skip to end
    <right expression>
    IFEQ .endIf // if right evaluates to zero (false), skip to end
.ifTrue
    <body of 'if' block>
.endIf

操作员的行为||有点不同;在这种情况下,逻辑看起来像这样:

    if (left)
        goto .ifTrue
    if (!right)
        goto .endIf
.ifTrue
    <do something>
.endIf

请注意,当右操作数的计算结果为 时,如何反转对右操作数的检查以避免额外的分支true。这种行为可以像这样在字节码中实现:

    <left operand>
    IFNE .ifTrue  // if left evaluates true, skip right, enter 'if' body
    <right operand>
    IFEQ .endIf   // if right evaluates false, skip 'if' body
.ifTrue
    <do something>
.endIf

何时推送您的操作数

请注意,您最初的问题表明您已经在堆栈上有左右操作数;那会很糟糕。您应该仅在左操作数评估为(非零) for或(零) for之后评估右操作数。如果正确的操作数引起副作用,过早地评估它会违反这些运算符的定义行为。true&&false||

于 2013-06-11T21:04:46.353 回答
1

有 Opcodes.IAND 和 Opcodes.LAND。你没有提到堆栈上的值是整数还是长整数,但我假设前者,所以我认为 Opcodes.IAND 是你想要的。

同样,OR 也有 Opcodes.IOR。对于 NOT,javac 似乎会发出 IFNE 和 ICONST_1 或 ICONST_0 指令,但如果您知道这些值是 1 或 0,那么您似乎可以发出 Opcodes.ICONST_1 后跟 Opcodes.IXOR。

请参阅 ASM 用户指南的附录 A,“字节码指令”,第 136 页:

http://download.forge.objectweb.org/asm/asm4-guide.pdf

于 2013-06-11T19:34:13.450 回答