-
-
[原创]科普一下CPUID的正确用法
-
2009-7-8 11:26
7359
-
使用了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
}
}
2.如果cpu支持cpuid指令,在使用某一cpuid function num之前
先判断是否支持该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);
3.参考相应处理器厂商的手册规范使用相应的function num
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(...)
{
//参考其他处理器厂商手册
}
详见附件源码
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法