How to Use the cpuid command in each version of VC and 64-bit

Source: Internet
Author: User
Tags microsoft c

We have discussed the use of cpuid commands (http://www.cnblogs.com/zyl910/archive/2012/05/14/dos16_getcpuid.html) in 16-bit dos real-time mode ). Nowadays, 64-bit windows is very popular. How to Use cpuid in 32/64-Bit mode? This article describes how to use the cpuid command in each version of VC and 64-bit.

1. intrinsics functions such as _ cpuid and _ cpuidex are recommended.

In 32-Bit mode, we can use embedded assembly to call the cpuid command. However, in 64-Bit mode, the VC compiler does not support embedded assembly.
As a result, Microsoft provides the intrinsics function-the compiler will compile the intrinsics function into corresponding machine commands, and support both 32-bit and 64-bit.
For example, the intrinsics function corresponding to the cpuid command is --

// http://msdn.microsoft.com/en-us/library/hskdteyh.aspxvoid __cpuid(   int CPUInfo[4],   int InfoType);void __cpuidex(   int CPUInfo[4],   int InfoType,   int ECXValue);

The infotype parameter of the _ cpuidex function is the eax parameter of the cpuid command, that is, the function ID. The ecxvalue parameter is the ECX parameter of the cpuid command, that is, the sub-function ID. The cpuinfo parameter is used to receive output eax, EBX, ECx, and EDX registers.
In earlier versions, cpuid only required one function ID parameter (eax). In this case, you can use the _ cpuid function.
Later, cpuid became more and more powerful, and a function ID parameter (eax) was not enough. Therefore, a sub-function ID (ECx) parameter was added, and _ cpuidex should be used.

Ii. Use Conditional compilation to determine the support of VC compiler for intrinsics functions (_ msc_ver)

When intrinsics functions such as _ cpuid and _ cpuidex are used, the following problems are encountered --
1. The VC compiler of earlier versions does not have the intrin. h header file. [Note]: Only vc2005 (or higher) has intrin. h and supports _ cpuid.
2. The VC compiler of earlier versions does not support _ cpuidex. [Note]: only some versions of vc2008 and intrin. h of vs2010 (or higher) have _ cpuidex.

In this case, you can use Conditional compilation to determine the version of the VC compiler.
_ Msc_ver is a predefined macro of the Microsoft C/csf-compiler --cl.exe during code compilation. Its value indicates the CL version and its type is "int ". For example --
# If _ msc_ver> = 1200 // VC ++ 6.0 or above
# If _ msc_ver> = 1300 // vc2003 or above
# If _ msc_ver> = 1400 // vc2005 or above
# If _ msc_ver> = 1500 // vc2008 or above
# If _ msc_ver> = 1600 // vc2010 or above

For example, if _ msc_ver is greater than or equal to 1400, We Can # include <intrin. h>. Then, use _ msc_ver to further judge the support of _ cpuid and _ cpuidex.

3. Use Conditional compilation to determine the 64-Bit mode (_ win64)

The _ win64 pre-processing macro can be used to determine whether the target platform is 64-bit.
Although the compiler automatically exports _ win64 when compiling programs on the x64 platform. However, the syntax highlighting of Visual Studio is unclear, and it may still be based on 32-bit code for syntax highlighting. Therefore, we recommend that you manually add _ win64 to the pre-processing macro of the project.

Iv. 32-bit Embedded Assembly implementation _ cpuidex Function

In 32-Bit mode, we can use Embedded Assembly to implement the _ cpuidex function. The Code is as follows --

Void _ cpuidex (int32 cpuinfo [4], int32 infotype, int32 ecxvalue) {If (null = cpuinfo) return; _ ASM {// load. read the parameter to the Register mov EDI, cpuinfo; // you are prepared to use EDI to address cpuinfo mov eax, infotype; MoV ECx, ecxvalue; // cpuid; // save. save the registers to cpuinfo mov [EDI], eax; MoV [EDI + 4], EBX; MoV [EDI + 8], ECx; MoV [EDI + 12], edX ;}}

 

 

5. All code

All code --

# Include <windows. h> # include <stdio. h> # include <tchar. h> # If _ msc_ver> = 1400 // vc2005 supports intrin. h # include <intrin. h> // All intrinsics functions # endifchar szbuf [64]; int32 dwbuf [4]; # If defined (_ win64) // inline assembly is not supported in 64-bit scenarios. intrinsics functions such as _ cpuid and _ cpuidex should be used. # Else # If _ msc_ver <1600 // vs2010. it is said that _ cpuidexvoid _ cpuidex (int32 cpuinfo [4], int32 infotype, int32 ecxvalue) is supported only after vc2008 SP1) {If (null = cpuinfo) return; _ ASM {// load. read the parameter to the Register mov EDI, cpuinfo; // you are prepared to use EDI to address cpuinfo mov eax, infotype; MoV ECx, ecxvalue; // cpuid; // save. save the registers to cpuinfo mov [EDI], eax; MoV [EDI + 4], EBX; MoV [EDI + 8], ECx; MoV [EDI + 12], edX ;}# endif // # If _ msc_ver <1600/V S2010. it is said that _ cpuidex # If _ msc_ver <1400 // vc2005 is supported only after vc2008 SP1 _ cpuidvoid _ cpuid (int32 cpuinfo [4], int32 infotype) {_ cpuidex (cpuinfo, infotype, 0 );} # endif // # If _ msc_ver <1400 // vc2005 supports _ cpuid # endif // # If defined (_ win64) // obtain the CPU vendor (vendor) /// result: the length of the string returned when the result is successful (generally 12 ). 0 is returned if the request fails. // Pvendor: string buffer for receiving vendor information. It must be at least 13 bytes. Int cpu_getvendor (char * pvendor) {int32 dwbuf [4]; If (null = pvendor) return 0; // function 0: vendor-ID and largest standard function _ cpuid (dwbuf, 0); // save. save to pvendor * (int32 *) & pvendor [0] = dwbuf [1]; // EBX: first four characters * (int32 *) & pvendor [4] = dwbuf [3]; // edX: four characters in the middle * (int32 *) & pvendor [8] = dwbuf [2]; // ECx: the last four characters pvendor [12] = '\ 0'; return 12 ;}// obtain the CPU trademark (brand) /// result: returns the string length (generally 48) when the string is successful ). 0 is returned if the request fails. // Pbrand: string buffer for receiving trademark information. It must be at least 49 bytes. Int cpu_getbrand (char * pbrand) {int32 dwbuf [4]; If (null = pbrand) return 0; // function 0x80000000: largest extended function number _ cpuid (dwbuf, 0x80000000); If (dwbuf [0] <0x80000004) return 0; // function 80000002 H, 80000003 H, 80000004 H: processor brand string _ cpuid (int32 *) & pbrand [0], 0x80000002); // the first 16 characters _ cpuid (int32 *) & pbrand [16], 0x80000003); // contains 16 characters in the middle _ cpuid (int32 *) & pbrand [32], 0x80000004 ); // The Last 16 characters pbrand [48] = '\ 0'; return 48;} int _ tmain (INT argc, _ tchar * argv []) {// _ cpuidex (dwbuf, 0, 0); // _ cpuid (dwbuf, 0); // printf ("%. 8x \ t %. 8x \ t %. 8x \ t %. 8x \ n ", dwbuf [0], dwbuf [1], dwbuf [2], dwbuf [3]); cpu_getvendor (szbuf); printf (" CPU vendor: \ t % s \ n ", szbuf); cpu_getbrand (szbuf); printf (" CPU name: \ t % s \ n ", szbuf); Return 0 ;}

 

Vi. Compatibility

32/64-bit support for the VC compiler --
32-bit: vc6 was the first to support compiling 32-bit intrinsics functions.
64-bit: vc2005 was the first to support compiling 64-bit intrinsics functions.

Compatibility of the methods in this article under the 32-bit compiler --
_ Cpuid: compatible with vc6 (or higher ).
_ Cpuidex: compatible with vc6 (or higher ).

Compatibility of the methods in this article under the 64-bit compiler --
_ Cpuid: compatible with vc2005 (or higher ).
_ Cpuidex: compatible with vc2010 (or higher ).

 

References --
Intel 64 and IA-32 ubuntures software developer's Manual Volume 2 (2a, 2b & 2c): Instruction Set Reference, A-Z. May 2012. http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.html
Intel processor identification and the cpuid instruction. Specification l 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
AMD cpuid specification. September 2010. http://support.amd.com/us/Embedded_TechDocs/25481.pdf
_ Cpuid, _ cpuidex. http://msdn.microsoft.com/en-us/library/hskdteyh.aspx
_ Cpuidex. http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/cac9c43b-ed72-4283-baa0-e7cd397591bc
Http://msdn.microsoft.com/en-us/library/b0084kay (V = vs.110). aspx
Predefine _ msc_ver macro by ownwaterloo. Http://www.cppblog.com/ownwaterloo/archive/2009/04/15/predefined_macro__MSC_VER.html

 

Download source code --
Http://files.cnblogs.com/zyl910/vcgetcpuid.rar

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.