我试图用逻辑和符号'&&'执行if语句。这是我想要做的事情:在asm中使用字节码的堆栈具有值0和1,我希望得到一个结果 '逻辑和'在我们的例子中它没有进入if语句。
我已经尝试过Opcodes.IFEQ和Opcodes.IFNE指令,但是没有用.Same跟'||'一样和'!'逻辑符号
有什么想法吗?
先谢谢。
答案 0 :(得分: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
请注意,您的原始问题表明您已经在堆栈中拥有左右操作数;那会很糟糕。您应该只评估左操作数评估为true
(非零)&&
或false
(零)||
后的右操作数 。如果右操作数导致副作用,过早地评估它会违反这些操作符的定义行为。
答案 1 :(得分:1)
有Opcodes.IAND和Opcodes.LAND。你没有提到堆栈上的值是int还是long,但我假设前者所以我认为Opcodes.IAND是你想要的。
同样,OR有Opcodes.IOR。对于NOT,javac似乎发出了IFNE和ICONST_1或ICONST_0指令,但是如果你知道值是1或0,那么你好像可以发出一个Opcodes.ICONST_1,然后是Opcodes.IXOR。
参见ASM用户指南的附录A,&#34;字节码说明&#34;,第136页: