提问人:Kamal Palei 提问时间:11/1/2023 最后编辑:Peter CordesKamal Palei 更新时间:11/2/2023 访问量:86
对于某些 EAX 值,不同的调用方会导致 CPUID 不一致
Inconsistent CPUID results with different callers for some EAX values
问:
unsigned int a, b;
a = 0;
b = 0;
for(a=0; a<6; a++)
{
__asm__("cpuid"
:"=a"(b) /** EAX into b (output) */
:"0"(a) /** a into EAX (input) */
:"%ebx","%ecx","%edx"); /** clobbered registers */
printf("a=%d, b=0x%x", a, b);
}
上面的代码打印了 a 和 b 的值。
在 Ubuntu 22 中,我用于 2 个项目的这部分代码。一个很小,另一个很大。我看到 a 和 b 的值打印在小型和大型项目中,如下所示。
小项目中的 a、b 值
a=0, b=0x20
a=1, b=0xb06a3
a=2, b=0xfeff01
a=3, b=0x0
a=4, b=0x0
a=5, b=0x40
a=6, b=0xdf8ff7
A、B值在更大的项目中
a=0, b=0x20
a=1, b=0xb06a3
a=2, b=0xfeff01
a=3, b=0x0
a=4, b=0x7c01c143
a=5, b=0x40
a=6, b=0xdf8ff7
您可以看到从 a=4 开始,上述两种情况下的 b 值不同。我很惊讶为什么值会变得不同,理想情况下,即使此代码从不同的项目运行,值也应该保持不变。
有人可以帮我理解为什么价值观会有所不同。
答:
3赞
teapot418
11/1/2023
#1
https://www.felixcloutier.com/x86/cpuid
4 是确定性缓存参数叶
返回的信息取决于 ECX 中的值。0 结果表示 ECX 不包含有效缓存的索引。
尝试将两者的 ECX 设置为相同的值,结果也应该稳定下来。
例:
__asm__("movl $0,%%ecx;\n\t"
"cpuid"
:"=a"(b) /** EAX into b (output) */
:"0"(a) /** a into EAX (input) */
:"%ebx","%ecx","%edx"); /** clobbered registers */
评论
0赞
Kamal Palei
11/1/2023
谢谢,如何设置 ECX 值。这是一个现有的代码,我不知道如何设置 ECX 值。请举个例子。
3赞
Peter Cordes
11/1/2023
@Austin:如果您不了解内联 asm 或不知道如何修改它,请将其替换为 from GCC 的 .应编译为相同的 asm。(至少对于 x86-64;我认为,在 32 位代码中,每次调用至少一些包装函数都会首先检查 CPUID 的可用性。__get_cpuid_count()
cpuid.h
0赞
Kamal Palei
11/1/2023
谢谢。如果我必须设置 ECX 值,如何做到这一点,任何提示都非常感谢。
0赞
teapot418
11/1/2023
@Austin刚刚添加了一个零的例子。语法可能有点傻,我对内联汇编不太熟悉。更多详情请见 ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
0赞
Kamal Palei
11/2/2023
你的例子效果很好。接受你的完美答案。
评论
cpuid.h
__get_cpuid_count
)