我有一个任务:在我的平台命令AVX、SSE (SSE1-SSE4.2)、FPU上检查exist。我的汇编程序代码不工作,我也无法解释原因。我认为这样的事情在不正确的描述输出修饰符。
unsigned int AVX;
unsigned int SSE1;
unsigned int SSE2;
unsigned int SSE3;
unsigned int SSSE3;
unsigned int SSE41;
unsigned int SSE42;
unsigned int FPU;
__asm__(
"cpuid\n\t"
"movl %%edx, %[AVX]\n\t"
"and $(1<<28), %[AVX]\n\t"
"movl %%edx, %[SSE1]\n\t"
"and $(1<<25), %[SSE1]\n\t"
"movl %%edx, %[SSE2]\n\t"
"and $(1<<26), %[SSE2]\n\t"
"movl %%ecx, %[SSE3]\n\t"
"and $(1<<9), %[SSE3]\n\t"
"movl %%ecx, %[SSSE3]\n\t"
"and $(1<<9), %[SSSE3]\n\t"
"movl %%edx, %[SSE41]\n\t"
"and $(1<<19), %[SSE41]\n\t"
"movl %%ecx, %[SSE42]\n\t"
"and $(1<<20), %[SSE42]\n\t"
"movl %%edx, %[FPU]\n\t"
"and $(1<<0), %[FPU]\n\t"
: [AVX] "=&r"(AVX), [SSE1]"=&r"(SSE1),
[SSE2]"=&r"(SSE2), [SSE3]"=&r"(SSE3),
[SSSE3]"=&r"(SSSE3), [SSE41]"=&r"(SSE41),
[SSE42]"=&r"(SSE42), [FPU]"=&r"(FPU)
: "a"(1)
: "cc"
);
cout << "AVX:" << (bool)AVX << endl;
cout << "SSE1:" << (bool)SSE1 << endl;
cout << "SSE2:" << (bool)SSE2 << endl;
cout << "SSE3:" << (bool)SSE3 << endl;
cout << "SSSE3:" << (bool)SSSE3 << endl;
cout << "SSE41:" << (bool)SSE41 << endl;
cout << "SSE42:" << (bool)SSE42 << endl;
cout << "FPU:" << (bool)FPU << endl;错误:“asm”操作数有不可能的约束
发布于 2022-05-27 17:08:29
在32位模式编程时,只有6或7个通用寄存器,因此编译器不能为寄存器分配八个输出操作数和一个输入操作数。您还忘记声明正确的选择器(cpuid clobbers eax、ebx、ecx和edx),如果不纠正,这将在运行时导致意外行为。
最好不进行内联组装,例如使用某种库或gcc内置的函数:
int AVX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42;
__builtin_cpu_init();
SSE1 = __builtin_cpu_supports("sse");
SSE2 = __builtin_cpu_supports("sse2");
SSE3 = __builtin_cpu_supports("sse3");
SSSE3 = __builtin_cpu_supports("ssse3");
SSE41 = __builtin_cpu_supports("sse4.1");
SSE42 = __builtin_cpu_supports("sse4.2");
AVX = __builtin_cpu_supports("avx");还可以考虑使用英特尔内部函数_may_i_use_cpu_feature和 interface。
请注意,检查这些位并不能告诉您操作系统是否实际启用了CPU功能,因此尝试使用这些特性的代码在运行时可能仍然会崩溃。
如果您必须对内联程序集执行此操作,请尽量减少内联程序集中的工作。
int eax = 1, ecx, edx;
int AVX, FPU, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42;
asm ("cpuid" : "+a"(eax), "=c"(ecx), "=d"(edx) :: "ebx");
FPU = edx & 1 << 0;
AVX = ecx & 1 << 28;
SSE1 = edx & 1 << 25;
SSE2 = edx & 1 << 26;
SSE3 = ecx & 1 << 0;
SSSE3 = ecx & 1 << 9;
SSE41 = ecx & 1 << 19;
SSE42 = ecx & 1 << 20;https://stackoverflow.com/questions/72408661
复制相似问题