繁体   English   中英

为一元not表达式生成JVM字节码

[英]Generating JVM bytecode for a unary not expression

假设您正在编写Java(或Java子集)编译器,并且您希望为一元而非表达式生成字节码, !E 您已通过类型检查,因此您知道E具有类型boolean ,即它将10推入操作数堆栈。

一种方法是(在Jasmin语法中):

E
ifeq truelabel
iconst_0
goto stoplabel
truelabel:
iconst_1
stoplabel:

即如果堆栈上有0则按1,否则按0.另一种方法,利用boolean只是一个值为10int的事实,就是说!E = (E + 1) % 2并生成

E
iconst_1
iadd
iconst_2
irem

使用一个优于另一个是否有优势? 或完全不同的东西?

我曾经尝试编写Java反编译器,所以我曾经知道javac生成了什么代码。 我记得,使用了javac 1.0.x !E = E ? false : true !E = E ? false : true使用javac 1.1时为!E = E ? false : true !E = E ^ 1 (按位异或)。

我不会指望以下定义在字节码级别上保持为真。

true == 1

在二进制级别(和它几乎与语言无关),布尔值通常定义为

false == 0
true != 0

javac编译器显然也遵循这个定义(我看到的javac字节码中的所有检查总是再次检查ZERO,从不反对ONE)。

并且将此定义用于布尔值而不是仅将1视为true是有意义的,C也以这种方式定义它(true只是!= 0,而不仅仅是1),并且在汇编代码中,这种约定也是常用的。 因此,java也使用这个定义,可以将java布尔值传递给其他代码而无需任何特殊转换。

我怀疑你的第一个代码示例(使用ifeq)是正确实现布尔值的非运算符的唯一方法。 如果布尔值没有明确表示为0/1,则^ 1方法(xor with 1)将失败。 任何其他int值都会导致表达式无法正常工作。

我听说模数操作可能非常慢。 我没有它的来源,但这是有道理的,因为添加比分割更简单。 再说一遍,可能会出现过多跳过程序计数器的问题,在这种情况下,if / else方法不能很好地工作。

话虽如此,我怀疑Neil的E ^ 1是最快的,但这只是一种预感。 你所要做的就是通过一个逻辑电路传递数字,你就完成了! 只需一次操作而不是少数操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM