GCC和Clang都支持一个实现定义的函数,名为\u builtin\u parity,该函数有助于确定数字的奇偶校验
根据GCC所述:
内置函数:int\u内置奇偶校验(无符号int x)
返回x的奇偶校验,即x模2中的1位数
这意味着,如果1位的数量为偶数,则将返回0,如果为奇数,则返回1
我在编译器资源管理器上测试的Clang也是如此
但是,实际奇偶校验标志是在设置位的数目为偶数时设置的
为什么会这样
它们只是不同的任意选择
首先请注意:”;“实际奇偶校验标志”;是仅在某些体系结构上提供的硬件功能;在目前主流使用的体系结构中,我认为x86是唯一一个有这样一个标志的体系结构。因此,这种旗帜的存在本身,更不用说确切的语义,在任何方面都不是一个普遍的标准
我认为GCC的选择更符合逻辑:0和1应该分别对应偶数和奇数,因为0是偶数,1是奇数。我不知道为什么x86及其前身选择了相反的做法。你可能不得不回到过去,询问设计师
无论如何,8086奇偶校验标志的实际值不是很重要;程序员通常会使用JPE和JPO汇编程序助记符来测试它,这些助记符只允许您指定;如果奇偶校验为偶数,则跳转;或;奇偶校验跳转“;无需记住哪一个对应于标志中的0或1位。只有当您希望通过PUSHF或LAHF实际检查标志寄存器中的位时,该值才会变得相关,这仅在非常模糊的情况下才有用
我看了一下历史。它从8086复制了8086的标志。它的前身,8008,也有一个对等的;触发器;,它似乎被设置为偶数奇偶校验,但有点不清楚,因为你只能有条件地跳转到触发器的状态,而不能真正地读取它。据说8008是从数据点2200派生出来的,它实际上以相反的方式记录奇偶校验翻转:设置为奇数,重置为偶数。但是80xx语义可能是一些没有任何深刻意义的内部实现细节,比如奇偶校验电路恰好以这种方式产生结果,并且他们没有费心添加另一个非门来反转它。任何进一步的调查都可能是关于Retrocomputing.SE的主题
x86奇偶校验标志对于GCC的\uuuuu内置奇偶校验()来说只是略微有用,因为它只测试一个字节。通过将其字节异或在一起,它可以用于更大的值,如果没有其他选项,GCC/clang将这样做。它通过在最后使用setnp而不是setp来处理标志的反向意义(人类程序员只需编写setpo,而不必考虑标志的设置/清除值)
然而,过去10年中几乎所有的x86 CPU都支持popcnt指令,如果可用,GCC/clang将使用它(然后只提取低位)