2016-07-21 103 views
3

Ich muss überprüfen, ECX für Bit 30, die eine CPU-Funktion für RDRAND erforderlich ist. Von der RDRAND Wiki,Was ist die CPUID-Standardfunktion 01H?

Wenn unterstützt, wird Bit 30 des ECX-Registers nach dem Aufruf der CPUID-Standardfunktion 01H gesetzt.

Ich weiß nicht genau, was das bedeutet. "Standardfunktion 01H"?

Bedeutet dies EAX = 80000001h? Ich bin mir nicht sicher, wie es weitergeht.

+1

Nein, es bedeutet 'EAX = 1'. Das Ausführen des CPUID-Befehls mit'EAX = 0x80000001' setzt einen anderen Satz von Informationen in ea/b/c/dx, der nichts über RDRAND enthält. –

+0

@PeterCordes Vielen Dank. – 8protons

Antwort

9

Ich denke, es bedeutet, dass% eax sollte 1 sein, wenn die cpuid-Funktion aufgerufen wird. Hardware-Jungs haben seltsame Konventionen, also sagen sie 01H statt 1 oder 0x1.

Siehe die intel manual Vol 2. Ch 3. Tabelle 3.8. Anfangswert von eax ist 01H. ECX bei der Rückkehr ist voller Feature-Informationen in Tabelle 3.10. Am Ende dieser Tabelle für Bit 30 steht, dass der Wert 1 bedeutet, dass der Prozessor RDRAND unterstützt.

Wenn Sie gcc haben, können Sie so etwas wie dies versuchen:

[email protected] ~/se $ cat foo.c 
#include <stdio.h> 
#include <cpuid.h> 
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; 
} 
[email protected] ~/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 

Es dauert ziemlich viel Zeit, um alles zu entschlüsseln, aber es gibt definiert in <cpuid.h>, die helfen können:

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

Es gibt eine Reihe mehr in der Header-Datei. Du wirst bemerken, dass Bit 30 meiner ecx (7fbee3bf) auf Level 1 gesetzt ist, also habe ich den RDRND Befehl verfügbar.

Weitere Informationen können durch diese Anweisung herausgezogen werden. Es gibt erweiterte Informationen, wobei eax das oberste Bit gesetzt hat, wenn cpuid aufgerufen wird. Je nach dem Wert von ecx, wenn Sie cpuid aufrufen, haben auch verschiedene Ebenen unterschiedliche "Blätter". Jemand, der sich langweilt, könnte einen oder zwei Tage damit verbringen, etwas zu programmieren, um die gesamte Merkmalsextraktion durchzuführen und es hübsch aussehen zu lassen. Alternativ könnte man ein "grep Flaggen/proc/cpuinfo" tun und so etwas wie dieses:

Fahnen: 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 NOPlat xtopology NONSTOP_TSC aperfmperf eagerfpu PNI pclmulqdq dtes64 überwachen 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

+1

Das ist richtig, in asm ['CPUID' verwendet 'eax' als Eingabe, um ein Blatt auszuwählen, und' e [a/b/c/d] x' als Ausgaben] (http://www.felixcloutier.com/ x86/CPUID.html). (Der inoffizielle HTML-Extrakt von Intels pdf ist leider ein Chaos für den CPUID-Eintrag) –

+2

Ich denke, dass eax ein Level auswählt, aber für einige Levels wird ecx verwendet, um ein Blatt zu bekommen. – evaitl

+0

oh, ja, ich habe es eine Weile nicht angeschaut und die Terminologie falsch verstanden. –