为什么没有ICMP指令?
正如你们中的一些人可能知道的那样,我们有大量的操作码来比较不同类型的原始值:
LCMP FCMPL FCMPG DCMPL DCMPG IFEQ IFNE IFLT IFGE IFGT IFLE IF_ICMPEQ IF_ICMPNE IF_ICMPLT IF_ICMPGE IF_ICMPGT IF_ICMPLE IF_ACMPEQ IF_ACMPNE ...
由于显而易见的原因,指令集的创建者并没有费心添加所有IF_LCMPEQ
, IF_FCMPLT
,……指令,但我想知道为什么没有ICMP
指令,看到它对于布尔值或Integer.compare(int, int)
非常有用Integer.compare(int, int)
。
已经有两个“主要基于意见”的近距离投票。 事实上,没有人可以在这里给出一个明确的答案,并且在试图争论25年前一群工程师做出的决定时可能会有一些牵手。 但我会试一试……
首先,我认为这个问题是合理的: int
类型是Java语言中最“突出”的类型(最后但并非最不重要的是因为它作为数组索引的作用)。 这与它在Java虚拟机中的特殊作用密切相关,其中语言中存在的所有(较小的)整数类型(如byte
或short
)都可以有效地转换为int
以用于所有计算。 或者,如Java虚拟机规范第2.11.7节中所述 :
由于强调了int比较,Java虚拟机为
int
类型提供了丰富的条件分支指令。
现在可以合理地问为什么这个“丰富的补充”似乎排除了对所有其他类型等效的指令。
没有icmp
指令的主要原因可能是既没有必要也没有益处。
将它用于Integer#compare(int, int)
的建议应用案例很难算作参数:这种方法的实现(即使存在icmp
)也不会
return icmp, arg0, arg1;
将方法转换为字节码可能相当复杂,并且考虑到Java语言本身的可能性,无论如何必须将这种方法等效地实现为
if (x > y) return 1; if (x < y) return -1; return 0;
显然可以将其转换为现有if_icmp>
指令的序列。
在这里,应该记住,这些比较指令的主要目的是分支 :它们导致跳转到不同的位置。 它们不是用于在堆栈上推送值,然后可以“用作方法的返回值”。 谈论语言和谈论虚拟机是两个完全不同的事情。
人们也可以转过头来问问题:为什么lcmp
, fcmp_
和dcmp_
指令分别可用于long
, float
和double
?
在这里,一个明确的答案要容易得多:为long
, float
和double
提供整套eq
, ne
, lt
, le
, gt
和ge
比较指令意味着18个额外的指令(甚至更多,使用NaN
处理浮动点类型)。 考虑到一个字节可能存在256个指令的硬限制,这就是很多。
通过为这些类型提供lcmp
, fcmp_
和dcmp_
指令,可用于int
的其余指令可用于模拟所有其他可能的比较情况。 但同样,这些主要用于分支 ,因此根本不需要icmp
指令,因为对于int
,所有必要的分支指令(“跳转条件”)已经可用。
- 后增量行为
- ResourceOwnerPasswordResourceDetails – 传递clientid和secret以生成oauth2令牌
- 使用SequenceGenerator的javax.persistence.EntityExistsException
- New Maven安装:mvn -version java.lang.ClassNotFoundException
- 书店应用程序的推荐系统
- 从日期选择器中获取价值
- ROT-13在java中的function?
- 无法找到SpelEvaluationException方法
- Tomcat(7,8)无法以java.lang.ClassNotFoundException开头:org.apache.tomcat.util.res.StringManager