Какова стандартная функция CPUID 01H?

Мне нужно проверить ECX для бит 30, который является функцией CPU, необходимой для RDRAND . Из RDRAND Wiki ,

Если поддерживается, бит 30 регистра ECX устанавливается после вызова стандартной функции CPUID 01H.

Я точно не знаю, что это значит. «Стандартная функция 01H »?

Означает ли это, что EAX = 80000001h ? Я не уверен, как действовать дальше.

Я думаю, это означает, что% eax должен быть 1 при вызове функции cpuid. У аппаратных парней есть странные соглашения, поэтому они говорят 01H вместо 1 или 0x1.

См. Руководство Intel Vol 2. Ch 3. Таблица 3.8. Начальное значение eax равно 01H. ECX по возвращении заполнен информацией о функциях в таблице 3.10. В нижней части таблицы для бит 30 указано, что значение 1 означает, что процессор поддерживает RDRAND.

Если у вас есть gcc, вы можете попробовать что-то вроде этого:

 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 

Потребуется довольно много времени, чтобы декодировать все, но в есть определения, которые могут помочь:

 /* %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) 

В файле заголовка есть еще больше. Вы заметите, что бит 30 моего ecx (7fbee3bf) установлен на уровне 1, поэтому я имею инструкцию RDRND.

Эта инструкция может быть выведена на более полную информацию. Существует расширенная информация, в которой eax имеет верхний бит, заданный при вызове cpuid. Также количество уровней имеет разные «листья» в зависимости от значения ecx при вызове cpuid. Кто-то, кто скучает, может потратить день или два на то, чтобы что-то сделать, чтобы сделать все извлечения функции и сделать ее красивой. В качестве альтернативы можно было бы сделать «grep flags / proc / cpuinfo» и получить что-то вроде этого:

флаги: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts