如何获知当前系统是否支持CPUID指令
CPUID指令是一个非常有用的指令,通过它能够获知相关CPU的具体规格,比如是否支持MMX/SSE/SSE2/SSE3/SSSE3/SSE4.1/SSE4.2指令,I/Dcache的大小,厂商等信息。因为一些老的CPU不支持它,为了程序有更好的兼容性,所以在使用之前最好要检查一下当前系统是否支持它。
那么如何检测呢?
很简单,EFLAGS寄存器的第21位用于指示是否CPUID能够被使用。如果软件能够对它进行设置或者清除,那么当前系统是可利用的。为了给大家清楚的说明这点,我这里给出了一个例子(因为水平有限,请大家将就一些啦J)。
int CPUID_IsSupported( void ) { int supported = 0;
__asm { pushfd pop eax mov ebx, eax xor eax, 200000h push eax popfd
pushfd pop eax push ebx popfd xor ecx, ecx mov edx, 1 xor eax, ebx cmovz edx, ecx mov supported, edx }
return supported; } |
对EFLAGS寄存器我们不能够直接访问,所以通过PUSHFD/POPFD来完成相应的修改动作。程序的基本思路是先将EFLAGS存放在EAX/EBX中,在修改它的第21位后通过POPFD来完成更新工作。在此之后,通过再次获取它的当前值(存放在EAX中)与修改前之值(存放在EBX中)进行比较,若发现一致,则表面当前系统不支持CPUID指令,反之亦然。
小结:
1. 程序中的push ebx和popfd这两条指令不是必须的。因为我喜欢干净,所以在这里添加了它们,主要目的是保持它的原有状态。如果喜欢效率的网友感觉不爽,完全可以剔除。
2. 没有对它进行什么优化,程序可能存在邋遢部分。如果哪位网友能够帮助优化,我将深表谢意。