如何使用__cpuid()检测CPU的AES-NI指令集支持情况?
检测CPU是否支持AES-NI(VS x64环境下)
问题背景
我需要检测我的CPU是否支持AES-NI指令集,网上的方案大多是内联汇编,但我用Microsoft Visual Studio编译x64程序,VS不支持x64内联汇编,x64环境对我来说很重要。我找到了__cpuid() intrinsic函数,但完全不懂汇编和intrinsic的用法(之前都是直接复制代码)。我自己写了一段代码,输出显示“AES-NI supported”,但不确定代码是否正确,能不能真正检测CPU的AES-NI支持:
int cpuInfo[4] = { -1 }; __cpuid(cpuInfo, 1); _Bool returned = ((cpuInfo[3] & 0x2000000) != 0); if (returned == 1) printf("AES-NI supported"); else printf("AES-NI not-supported");
解答
你的代码是完全正确的,可以准确检测CPU是否支持AES-NI指令集,我给你拆解一下为什么没问题:
- 首先,
__cpuid(cpuInfo, 1):调用这个intrinsic函数时传入参数1,会让CPU返回自身的特性支持信息,结果会存在cpuInfo数组里,其中cpuInfo[3]对应CPUID指令返回的EDX寄存器值。 - 然后,
0x2000000这个十六进制数,对应的是EDX寄存器的第25位(从0开始计数),而CPU支持AES-NI的话,这一位会被置为1。 - 最后通过按位与操作
cpuInfo[3] & 0x2000000判断这一位是否为1,从而得出是否支持AES-NI的结论。
另外给你提个小建议:把代码整理得更易读一些,同时别忘了包含必要的头文件,不然VS可能找不到__cpuid的声明:
#include <stdio.h> #include <intrin.h> // 必须包含这个头文件才能使用__cpuid int main() { int cpuInfo[4] = { -1 }; __cpuid(cpuInfo, 1); _Bool hasAES = (cpuInfo[3] & 0x2000000) != 0; if (hasAES) { printf("AES-NI supported\n"); } else { printf("AES-NI not supported\n"); } return 0; }
内容的提问来源于stack exchange,提问作者Tom Clabault
相关产品推荐
相关产品推荐

