首先,关于IEEE754标准中所规定的单精度浮点的规格化、非规格化、无穷大以及非数的定义可以详见此博文《IEEE754规范: 四, 非规格数, ±infinity, NaN》
下图为Wiki中关于IEEE754的单精度与双精度的详细描述,首先是它们的二进制数表达图:
下图是Wiki上对浮点数的无穷大、非数等表示的消息描述:
最后呈现的是IEEE754浮点数表示的样例表
Intel官方编程指南已经对通用算术比较指令所产生的条件码已经描述得非常详细了,在《Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 1: Basic Architecture》中的附录B。
各位也可以通过直接搜索 “condition code” 来搜索到相关内容。
但是,此文档对浮点数比较所引发的EFLAGS标志位的变化所对应的条件码几乎没怎么描述,因此本博文将详细列出 UCOMISS 指令所对应可用的条件码。
UCOMISS
这条指令会根据两个比较操作数的数值得到对应的四种不同的结果,对于每一种结果,OF、AF、SF 这三个标志位都会被清零,而 ZF、CF、PF 这三个标志位会根据比较结果的不同而有所不同。因此我们在实际应用场合不能用 L、G 等表示通用算术比较指令得到的带符号的条件码,因为它们主要依赖 OF 和 AF 这两个标志位。下面详细介绍这四种结果。
比较结果 | 描述 | ZF | PF | CF |
---|---|---|---|---|
UNORDERED | 当任一一个操作数为NaN时(包括QNaN和SNaN) | 1 | 1 | 1 |
大于 | 当第一个操作数大于第二个操作数时 | 0 | 0 | 0 |
小于 | 当第一个操作数小于第二个操作数时 | 0 | 0 | 1 |
等于 | 当第一个操作数相等于第二个操作数时 | 1 | 0 | 0 |
这里稍微科普一下关于QNaN和SNaN。QNaN表示“Quiet Not a Number”,指示当前所产生的非数不需要发出异常信号;而SNaN表示“Signaling Not a Number”,指示当前所产生的非数是情况比较严重的,可能需要发出异常信号(比如 0.0 / 0.0 之类的)。
这么一来,我们对照附录B中罗列的条件码就能相应得到浮点比较的条件码了。这里列出可用的条件码:
条件码 | 比较结果 | 标志位判定 |
---|---|---|
B/NAE | 小于 / UNORDERED | CF=1 |
AE/NB | 大于/等于 | CF=0 |
E/Z | 等于 / UNORDERED | ZF=1 |
NE/NZ | 大于/小于 | ZF=0 |
BE/NA | 小于/等于 / UNORDERED | (CF|ZF)=1 |
A/NBE | 大于 | (CF|ZF)=0 |
P/PE | UNORDERED | PF=1 |
NP/PO | 大于/小于/等于 —— (ORDERED) | PF=0 |
此外,像 CMPNEQxx
、CMPNLTxx
以及 CMPNLExx
等指令(这里的xx可以是SS、SD和PS,而PD有自己独立的一套条件码)在当某一操作数为非数时,条件也依然成立,即会将目的操作数对应的向量元素全置为1。
x86架构中通用目的以及浮点计算条件码表
请看此图:
上图中针对通用目的操作数比较所用到的术语:Above
表示无符号大于;Below
表示无符号小于;Greater
表示带符号大于;Less
表示带符号小于。
x86架构中关于浮点比较的条件码表
请看此图:
x87 FPU中对标志位的影响表
请看此图:
对于x87 FPU的浮点比较以及SSE、AVX等中的浮点比较(比如:UCOMISS
),Above
表示大于;Below
表示小于。
此外,对于SSE、AVX指令的浮点比较(比如:UCOMISS
),影响的是EFLAGS标志位:ZF、PF和CF。
还有需要重点关注的是:对于 Unordered (即,非数)比较结果,不仅PF标志,ZF与CF标志均置为1!因此,我们不能仅仅用ZF和CF来判定当前浮点数的大小关系,具体需要看哪些比较结果使得PF必定为0的。如果某个比较结果使得CF为1或者ZF为1,那么可能需要进行条件转化或是做额外处理来判定非数的可能,如上述第二张表所示。
ARM架构中的条件码表
请看此图:
上表中所出现的术语——HI
表示Higher,即无符号大于;LO
表示Lower,即无符号小于;GT
表示Greater Than,即带符号大于;LT
表示Less Than,即带符号小于;HS
表示Higher or Same,即无符号大于等于;LS
表示Lower or Same,即无符号小于等于;GE
表示Greater than or Equal,即带符号大于等于;LE
表示Less than or Equal,即带符号小于等于。ARM官方文档的条件码表非常全,一张表就将通用目的操作数的比较以及浮点数比较所产生的条件码以及说明都列全了。