【发布时间】:2013-04-04 07:09:38
【问题描述】:
我看到在 x86 CPU 中,奇偶校验标志 (PF) 在设置为 1 的位数为偶数时设置,并且仅测试值的第一个字节(低 8 位)。
我不确定的唯一情况是当我们处理值 0 时。
我至少看到了其他问题,其中奇偶校验标志似乎设置为 1,值为 0。
例如,对于值 8000h,低 8 位全为 0,则称奇偶校验标志为 1。
那么,我是否应该接受设置为 1 的 0 位启用奇偶校验标志,就像设置为 1 的偶数位一样?
【问题讨论】:
我看到在 x86 CPU 中,奇偶校验标志 (PF) 在设置为 1 的位数为偶数时设置,并且仅测试值的第一个字节(低 8 位)。
我不确定的唯一情况是当我们处理值 0 时。
我至少看到了其他问题,其中奇偶校验标志似乎设置为 1,值为 0。
例如,对于值 8000h,低 8 位全为 0,则称奇偶校验标志为 1。
那么,我是否应该接受设置为 1 的 0 位启用奇偶校验标志,就像设置为 1 的偶数位一样?
【问题讨论】:
0 的位数是偶数,所以答案是肯定的。
测试:
// compiled with Open Watcom C/C++ 1.9
#include <stdio.h>
unsigned parity(unsigned v)
{
unsigned p = 0;
__asm
{
mov eax, v
or eax, eax
pushf
pop eax
shr eax, 2
and eax, 1
mov p, eax
}
return p;
}
int main(void)
{
unsigned i;
for (i = 0; i < 8; i++)
printf("PF(%u) = %u\n", i, parity(i));
return 0;
}
输出:
PF(0) = 1
PF(1) = 0
PF(2) = 0
PF(3) = 1
PF(4) = 0
PF(5) = 1
PF(6) = 1
PF(7) = 0
【讨论】:
parity() 编写asm 的最低效率的方式。 cmp [v], 0 / setp byte ptr [p] 应该可以解决问题。或者使用mov 和test eax,eax 加载它。但请记住,PF 仅从值的低字节设置,即使是 32 位 test 或 cmp。)
setp,您也可以使用lahf,这仍然比pushf / pop eax 更有效。 (例如,pushf 在 Haswell 上是 3 微秒。但它并不像 popf 那样糟糕,因为除了条件代码之外,读取 IF、DF 和其他 EFLAGS 位比编写它们便宜得多)。