我正在尝试使用逻辑和符号“&&”执行 if 语句。这是我想要做的事情:asm 字节码中的 Μy 堆栈具有值 0 和 1,我想得到一个带有“逻辑和”的结果,在我们的例子中它不会进入 if 语句。
我已经尝试过 Opcodes.IFEQ 和 Opcodes.IFNE 指令,但不起作用。'||'也是如此 和 '!' 逻辑符号
有任何想法吗?
&&
和的字节码模式||
想想短路操作员喜欢什么&&
或||
实际做了什么。你有一些条件分支。让我们考虑一下&&
。您正在有效评估的是:
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
||
有 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 页: