Quelle est la fonction standard 01H du CPUID?

J’ai besoin de vérifier ECX pour le bit 30, qui est une fonctionnalité de processeur nécessaire pour RDRAND . Du Wiki RDRAND ,

S’il est pris en charge, le bit 30 du registre ECX est défini après l’appel de la fonction standard CPUID 01H.

Je ne sais pas exactement ce que cela signifie. “Fonction standard 01H “?

Est-ce que cela signifie EAX = 80000001h ? Je ne sais pas trop comment procéder.

Je pense que cela signifie que% eax devrait être 1 lors de l’invocation de la fonction cpuid. Les gars du matériel ont des conventions étranges, ils disent donc 01H au lieu de 1 ou 0x1.

Voir le manuel Intel Vol 2. Ch 3. Tableau 3.8. La valeur initiale de eax est 01H. Le retour sur ECX est plein d’informations sur les fonctionnalités du tableau 3.10. Au bas de cette table pour le bit 30, il est indiqué qu’une valeur de 1 signifie que le processeur prend en charge RDRAND.

Si vous avez gcc, vous pouvez essayer quelque chose comme ceci:

 evaitl@bb ~/se $ cat foo.c #include  #include  int main(){ unsigned eax=0, ebx=0, ecx=0, edx=0; unsigned max_lvl=__get_cpuid_max(0,&ebx); printf("Max level: %d sig %x\n",max_lvl,ebx); ebx=0; for(int lvl=0; lvl<=max_lvl; ++lvl){ __get_cpuid(lvl,&eax, &ebx, &ecx, &edx); printf("lvl %-2d eax %08x ebx %08x ecx %08x edx %08x\n", lvl, eax, ebx, ecx, edx); eax=ebx=ecx=edx=0; } return 0; } evaitl@bb ~/se $ ./foo Max level: 13 sig 756e6547 lvl 0 eax 0000000d ebx 756e6547 ecx 6c65746e edx 49656e69 lvl 1 eax 000306e4 ebx 07200800 ecx 7fbee3bf edx bfebfbff lvl 2 eax 76036301 ebx 00f0b2ff ecx 00000000 edx 00ca0000 lvl 3 eax 00000000 ebx 00000000 ecx 00000000 edx 00000000 lvl 4 eax 00000000 ebx 00000000 ecx 00000000 edx 00000000 lvl 5 eax 00000040 ebx 00000040 ecx 00000003 edx 00001120 lvl 6 eax 00000077 ebx 00000002 ecx 00000009 edx 00000000 lvl 7 eax 00000000 ebx 00000000 ecx 00000000 edx 00000000 lvl 8 eax 00000000 ebx 00000000 ecx 00000000 edx 00000000 lvl 9 eax 00000001 ebx 00000000 ecx 00000000 edx 00000000 lvl 10 eax 07300403 ebx 00000000 ecx 00000000 edx 00000603 lvl 11 eax 00000000 ebx 00000000 ecx 0000006e edx 00000007 lvl 12 eax 00000000 ebx 00000000 ecx 00000000 edx 00000000 lvl 13 eax 00000000 ebx 00000000 ecx 00000000 edx 00000000 

Il faudra un peu de temps pour tout décoder, mais il existe des définitions dans qui peuvent aider:

 /* %ecx */ #define bit_SSE3 (1 << 0) #define bit_PCLMUL (1 << 1) #define bit_LZCNT (1 << 5) #define bit_SSSE3 (1 << 9) #define bit_FMA (1 << 12) #define bit_CMPXCHG16B (1 << 13) #define bit_SSE4_1 (1 << 19) #define bit_SSE4_2 (1 << 20) #define bit_MOVBE (1 << 22) #define bit_POPCNT (1 << 23) #define bit_AES (1 << 25) #define bit_XSAVE (1 << 26) #define bit_OSXSAVE (1 << 27) #define bit_AVX (1 << 28) #define bit_F16C (1 << 29) #define bit_RDRND (1 << 30) 

Il y en a beaucoup plus dans le fichier d'en-tête. Vous remarquerez que le bit 30 de mon ecx (7fbee3bf) est défini sur le niveau 1, de sorte que l'instruction RDRND est disponible.

Plus d'informations peuvent en réalité être extraites par cette instruction. Il existe des informations étendues avec eax dont le bit supérieur est défini lors de l'appel de cpuid. De plus, un certain nombre de niveaux ont des "feuilles" différentes en fonction de la valeur de ecx lorsque vous appelez cpuid. Quelqu'un qui s'ennuie pourrait passer un jour ou deux à coder quelque chose pour faire toute l'extraction de fonctionnalités et la rendre jolie. Alternativement, on pourrait faire un "grep flags / proc / cpuinfo" et obtenir quelque chose comme ceci:

drapeaux de vp vmx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdr et la v;