assembly CPU上奇偶校验标志的用途是什么?

yeotifhr  于 2023-01-21  发布在  其他
关注(0)|答案(5)|浏览(194)

一些CPU(特别是x86 CPU)在其状态寄存器上有一个奇偶校验标志。这个标志指示操作结果的位数是奇数还是偶数。

奇偶校验标志在编程环境中有什么实际用途?

  • 旁注:* 我假设它是为了与奇偶校验位一起使用,以便执行基本的错误检查,但这样的任务似乎不太常见,需要保证整个CPU标志。
jchrr9hc

jchrr9hc1#

回到“过去”,当性能总是一个关注点时,它更有意义。它被用于通信中来验证完整性(进行错误检查)并且相当大一部分通信是串行的,这比并行通信更多地使用奇偶校验。无论如何,CPU只使用8个异或门来计算它是微不足道的,但在其他方面,如果没有CPU的支持,计算是相当困难的。如果没有硬件的支持,它需要一个实际的循环(可能展开)或查找表,这两个都非常耗时,所以好处超过了成本。现在,它更像是一个遗迹。

hxzsmxv2

hxzsmxv22#

奇偶校验标志是过去在软件中进行奇偶校验的遗留物。

    • TL; DR**

什么是奇偶校验

正如Randall Hyde在《汇编语言的艺术》(The Art of Assembly Language)第二版中所说:
奇偶校验是一种非常简单的错误检测方案,最初用于电报和其它串行通信协议。其思想是计算一个字符中设置位的数量,并在传输中包括一个额外的位,以指示该字符包含偶数还是奇数个设置位。传输的接收端也将计算这些位,并验证额外的"奇偶校验"位是否指示成功传输。

为什么要将奇偶校验标志添加到CPU体系结构中

在过去,serial communication hardware (UART)缺乏对传输数据进行奇偶校验的能力,所以程序员必须在软件中进行。还有一些非常古老的设备,如纸带打孔机和阅读器,使用7个数据位和一个奇偶校验位,并且程序员必须在软件中进行奇偶校验以验证数据完整性。为了能够使用奇偶校验位进行错误检测,通信各方必须事先就每个传输的字节应该具有奇还是偶奇偶校验达成一致(通信协议的一部分)。
在没有CPU支持的软件中进行奇偶校验的主要方法是 * 位计数 * 或使用 * 查找表 *。与在CPU中通过单个指令计算奇偶校验标志相比,这两种方法都非常昂贵。因此,英特尔在1972年4月将奇偶校验标志引入其8008 8-bit CPU。下面是一个示例,说明如何在接收端测试每个字节的完整性。

mov        al,<byte to be tested>
test       al,al
jp         <somewhere>         ; byte has even parity
                               ; byte has odd parity

然后程序可以根据奇偶校验标志的值执行各种条件逻辑。

英特尔CPU中条件奇偶校验指令的演变

      • 1972年**-奇偶校验标志首次引入英特尔8008。有用于跳转(JPOJPE)、调用(CPOCPE)和返回(RPORPE)的条件指令。
      • 1978**-英特尔8086丢弃除条件跳转(JNP/JPOJP/JPE)以外的所有内容。
      • 1985**-英特尔80386添加了条件集合指令SETPE/SETPSETPO/SETNP
      • 1995年**-奔腾Pro添加了条件移动指令CMOVP/CMOVPECMOVNP/CMOVPO

这组使用奇偶校验标志的指令从那时起一直保持不变。
现在这个标志的主要用途已经被硬件取代了。引用Randall Hyde在 * The Art of Assembly Language,2nd Edition * 中的话:
使用奇偶校验进行错误检查的串行通信芯片和其他通信硬件通常在硬件中计算奇偶校验;你不需要用软件来实现这个目的。
奇偶校验标志的古老性可由以下事实证明:它仅适用于低8位,因此用途有限。根据英特尔® 64和IA-32架构软件开发人员手册,奇偶校验标志为:
如果结果的最低有效字节包含偶数个1位,则置1;否则清除。
有趣的事实:用网络工程师Wolfgang Kern自己的话说,他扫描了他在某个时候为JPEJPO指令编写的所有代码(约14 GB),发现它只存在于RS232驱动器模块和一个非常古老的8位计算中。

来源

n3ipq98p

n3ipq98p3#

有一个实用的微优化可以通过奇偶校验实现--那就是位交换,例如在使用蝶形内核的傅立叶变换地址生成中使用的位交换。
要交换第7位和第0位,可以利用(a&0x81)的奇偶校验,后跟条件(a^= 0x 81)。对第6/1、5/2和4/3位重复上述操作。

0g0grzrc

0g0grzrc4#

我个人认为,奇偶校验标志失效的谣言被夸大了。它在某些情况下非常有用。考虑下面的汇编语言过程:

push       rbp
mov        rbp, rsp
xor        eax, eax
ucomisd    xmm0, xmm1
setnp      al
pop        rbp
ret

它接受xmm0和xmm1中的两个双精度参数,并返回一个布尔结果,看看你是否能弄清楚它在做什么。😄

kh212irz

kh212irz5#

有时候,您只需要等待,直到有人为废弃的功能提出一个聪明的用例:Efficient n-states on x86 systems
只需一个测试,就可以检查变量的4种状态,如下所示:

; flag = {-1, 0, 1, 3} 
testl $-1,flag     ; and flag with -1 and set condition codes
jz    case_1       ; jump if flag == 0
js    case_2       ; jump if flag < 0
jp    case_3       ; jump if flag > 0 and flag has even parity
; flag > 0 and has odd parity

此外,可以以JNNJNJJNNJN...或NJJNJNNJJNJ...的方式进行分支(J=跳转;N=无跳转)
我能想到的是:

  • JNNJ是NJJN的倒数
  • JNJ、NJN、JNNJ和NJJN也是回文
  • 你可以在一组3个中只循环一次,或者在一组3个中循环两次,然后重复。这实际上在某个地方的组装演示中使用。只要找到你需要的确切图案的正确起点。

相关问题