使用了cpuid指令的程序要想通用的话:
1.判断SPU是否支持cpuid指令
方法:看eflags的第21位(ID位)能否被改变
代码:
BOOL __declspec(naked) IsCpuidValid() { __asm { pushfd pop eax //eax = eflags mov ebx, eax xor eax, 00200000h //toggle bit 21, eflags.[ID] push eax popfd pushfd pop eax cmp eax, ebx jz NO_CPUID mov eax, 1 ret NO_CPUID: xor eax, eax ret } }
先判断是否支持该function num:
代码:
CPUID_ARGS ca; ca.eax = 0; cpuid32(&ca); char Vendor[13]; *((PULONG)&Vendor[0]) = ca.ebx; *((PULONG)&Vendor[4]) = ca.edx; *((PULONG)&Vendor[8]) = ca.ecx; Vendor[12] = '\0'; printf("CPU Vendor: %s\n", Vendor); printf("Max Standard function: 0x%08x\n", ca.eax); ca.eax = 0x80000000; cpuid32(&ca); printf("Max Extended function: 0x%08x\n", ca.eax);
代码:
if(strcmp(Vendor, "GenuineIntel") == 0) { //参考IPM-241618 if(ca.eax >= 0x80000004) //support brand string { char Brand[48]; ca.eax = 0x80000002; cpuid32(&ca); *((PULONG)&Brand[0]) = ca.eax; *((PULONG)&Brand[4]) = ca.ebx; *((PULONG)&Brand[8]) = ca.ecx; *((PULONG)&Brand[12]) = ca.edx; ca.eax = 0x80000003; cpuid32(&ca); *((PULONG)&Brand[16]) = ca.eax; *((PULONG)&Brand[20]) = ca.ebx; *((PULONG)&Brand[24]) = ca.ecx; *((PULONG)&Brand[28]) = ca.edx; ca.eax = 0x80000004; cpuid32(&ca); *((PULONG)&Brand[32]) = ca.eax; *((PULONG)&Brand[36]) = ca.ebx; *((PULONG)&Brand[40]) = ca.ecx; *((PULONG)&Brand[44]) = ca.edx; printf("Brand: %s\n", Brand); } } else if(strcmp(Vendor, "AuthenticAMD") == 0) { //参考APM-25481 if(ca.eax >= 0x80000004) //support brand string { char Brand[48]; ca.eax = 0x80000002; cpuid32(&ca); *((PULONG)&Brand[0]) = ca.eax; *((PULONG)&Brand[4]) = ca.ebx; *((PULONG)&Brand[8]) = ca.ecx; *((PULONG)&Brand[12]) = ca.edx; ca.eax = 0x80000003; cpuid32(&ca); *((PULONG)&Brand[16]) = ca.eax; *((PULONG)&Brand[20]) = ca.ebx; *((PULONG)&Brand[24]) = ca.ecx; *((PULONG)&Brand[28]) = ca.edx; ca.eax = 0x80000004; cpuid32(&ca); *((PULONG)&Brand[32]) = ca.eax; *((PULONG)&Brand[36]) = ca.ebx; *((PULONG)&Brand[40]) = ca.ecx; *((PULONG)&Brand[44]) = ca.edx; printf("Brand: %s\n", Brand); } } else //if(...) { //参考其他处理器厂商手册 }