某些 CPU(尤其是 x86 CPU)在其状态寄存器上具有奇偶校验标志。该标志指示运算结果的位数是奇数还是偶数。
奇偶校验标志在编程上下文中的实际实际用途是什么?
旁注: 我假设它打算与奇偶校验位一起使用以执行基本的错误检查,但这样的任务似乎不常见以保证整个 CPU 标志。
某些 CPU(尤其是 x86 CPU)在其状态寄存器上具有奇偶校验标志。该标志指示运算结果的位数是奇数还是偶数。
奇偶校验标志在编程上下文中的实际实际用途是什么?
旁注: 我假设它打算与奇偶校验位一起使用以执行基本的错误检查,但这样的任务似乎不常见以保证整个 CPU 标志。
回到性能总是令人担忧的“旧时代”,它更有意义。它用于通信以验证完整性(进行错误检查),并且大部分通信是串行的,与并行通信相比,它更多地使用奇偶校验。在任何情况下,CPU 仅使用 8 个 XOR 门来计算它是微不足道的,但如果没有 CPU 支持,则很难计算。在没有硬件支持的情况下,它需要一个实际的循环(可能是展开的)或一个查找表,这两者都非常耗时,因此收益大于成本。但现在,它更像是一种遗迹。
Parity Flag 是过去在软件中进行奇偶校验的遗留物。
TL;博士
正如 Randall Hyde 在The Art of Assembly Language, 2nd Edition中所说:
奇偶校验是一种非常简单的错误检测方案,最初由电报和其他串行通信协议使用。这个想法是计算一个字符中设置位的数量,并在传输中包含一个额外的位,以指示该字符是否包含偶数或奇数个设置位。传输的接收端也会对比特进行计数,并验证额外的“奇偶校验”比特是否表明传输成功。
在过去,串行通信硬件 (UART)缺乏对传输数据进行奇偶校验的能力,因此程序员必须在软件中进行。还有一些非常古老的设备,如纸带打孔器和阅读器,使用 7 个数据位和一个奇偶校验位,程序员必须在软件中进行奇偶校验以验证数据完整性。为了能够使用奇偶校验位进行错误检测,通信各方必须事先就每个传输的字节应该具有奇校验还是偶校验(通信协议的一部分)达成一致。
在没有 CPU 支持的情况下,在软件中进行奇偶校验的主要方法是位计数或使用查找表。与在 CPU 中通过单条指令计算的奇偶校验标志相比,两者都非常昂贵。出于这个原因,英特尔在 1972 年 4 月将奇偶校验标志引入了他们的8008 8 位 CPU。下面是一个示例,说明从那时起如何在接收端测试每个字节的完整性。
mov al,<byte to be tested>
test al,al
jp <somewhere> ; byte has even parity
; byte has odd parity
然后程序可以根据奇偶校验标志的值执行各种条件逻辑。
JPO
, JPE
)、调用 ( CPO
, CPE
) 和返回 ( RPO
, RPE
)。JNP/JPO
, JP/JPE
) 之外的所有内容。SETPE/SETP
并SETPO/SETNP
与 Intel 80386 一起添加。CMOVP/CMOVPE
。CMOVNP/CMOVPO
从那时起,这组使用奇偶校验标志的指令保持不变。
如今,此标志的主要用途已被硬件接管。引用 Randall Hyde 在The Art of Assembly Language, 2nd Edition中的话:
使用奇偶校验进行错误检查的串行通信芯片和其他通信硬件通常在硬件中计算奇偶校验;您不必为此目的使用软件。
奇偶校验标志的古老由它仅在低 8 位上工作这一事实证明,因此它的用途有限。根据英特尔® 64 和 IA-32 架构软件开发人员手册,奇偶校验标志为:
如果结果的最低有效字节包含偶数个 1,则设置;否则清除。
有趣的事实:用他自己的话来说,网络工程师 Wolfgang Kern 扫描了他在某个时间点 (~14 GB) 编写的所有代码JPE
和JPO
指令,发现它只存在于一个 RS232 驱动模块和一个非常古老的 8 位计算中。
奇偶校验可以实现一种实用的微优化——例如在使用蝶形内核的傅立叶变换地址生成中使用的位交换。
要交换第 7 位和第 0 位,可以利用 (a&0x81) 后跟条件 (a^=0x81) 的奇偶校验。对位 6/1、5/2 和 4/3 重复此操作。
个人认为,平价旗死的传言被夸大了。在某些情况下它可能非常有用。考虑以下汇编语言过程:
push rbp
mov rbp, rsp
xor eax, eax
ucomisd xmm0, xmm1
setnp al
pop rbp
ret
这需要 xmm0、xmm1 中的两个双精度参数,并返回一个布尔结果。看看你能不能弄清楚它在做什么。