is an instruction added to Intel Pentiums (and some
later 80486's) that enables programmers to determine what kind of
features the current CPU
supports, who made it, various extensions and
abilities, and cache information.
This article will show you how to get information using
, and how to interpret
that information to detect support for MMX and its extensions, 3DNow! and its extensions, SSE and
its extensions, and some other useful features.
There are many ways to use
, depending on where you
are working. There is inline assembly for GCC
(both different), as well as using it in plain assembly files (for
uses the value in
, and returns data
eax, ebx, ecx,
input is known as the "Function" input. It can have
values from 0x00000000 to 0x00000001, and 0x80000000 to 0x80000008.
in GCC, it is normally easiest to just define a
macro, like this:
__asm__ __volatile__ ("cpuid":\
"=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func));
In the above, you simply put whatever function number you want in for
func, and put in 4 variables that will get the output values of
In NASM, you simply use the instruction
, and handle the
outputs as desired.
In MSVC, it's a bit longer, but still not too crazy. (Please keep in mind
that I don't use MSVC much at all anymore, so this isn't tested).
mov eax, func\
mov a, eax\
mov b, ebx\
mov c, ecx\
mov d, edx\
And then you can call it with the same above snippet.
CPUID — Functions
As mentioned above,
has many functions, depending
on the microprocessor it is on. We'll start from the
Function 0 is used to get the Vendor String from the CPU. It also tells
us the maximum function supported by
-supporting CPU will allow at least this function. I'll describe
as many functions as I find information about, but please keep in mind that not all CPUs
will handle all function values.
gets the maximum function call value.
gets the first 4 bytes of the Vendor String.
gets the second 4 bytes of the Vendor String.
gets the last 4 bytes of the Vendor String.
When all the Vendor String bytes are lined up, they'll spell a clever
phrase depending on who manufactured it.
uses "AuthenticAMD", and
There were other players back in the day, but they seem to have gone out
of business or left the CPU market. They were
(now owned by Via
), Centaur (also owned
by Via?), NexGen (sold to AMD in 1996), National Semiconductor
processor was called the 'Geode'),
(violated Intel patents, so they were never sold Stateside. Seemed to
only produce some 486's), and Rise
sold to SiS in
Function 0x1 returns the Processor Family, Model, and Stepping information
gets the Standard Feature Flags.
|16-19||Extended Model Number|
|20-27||Extended Family Number|
What we're really interested in is what's in
Standard Feature Flags. This register holds a bitmask of
all the features needed to determine which SIMD extensions our CPU
supports. If we're trying to detect SSE3
we'll also want to look at
Please note that these features are very abridged. There are many
other features in the other bits of this register.
Function 0x2 tells us some information about the processor's cache and
Function 0x3 gets us the bottom 64 bits of the processor's 96 it serial number in
This was only used on Pentium III processors. The top 32 bits are the Processor Signature,
which is the value of
=1 (Function 1).
Function 0x4 returns some more detailed information about the cache as well as information regarding
how many cores the processor has. It looks like Function 0x4 can be used multiplt times to get more
information about the various caches the CPU is aware of (?).
Function 0x5 is used for the
instructions. These are used only by the Operating System,
so they're not very useful for user applications.
Function 0x6 provides us with some information on Power Management and Temperature Control. Again,
these are perating System features, and we won't bother with them much here.
While Intel was off making
early on, they didn't
mention how they planned to use the bits. So when other vendors started
making extensions of their own, they needed a way to use
to indicate their features without stepping on any toes. To perform this,
they use the second function range (0x80000000+). These functions act just
like their lower-valued counterparts.
Function 0x80000000 is just like Function 0, except it returns the highest
function supported. This is probably something like
0x80000008 (at least, for Athlons). The other registers are kept the same
(the Vendor String).
Function 0x80000001 returns values
into the same registers as Function 1, but some of the
meanings have changed.
gets the Extended Stepping/Mode/Family Numbers.
gets the Extended Feature Flags.
|22||AMD MMX Extensions|
Please Note that this is abridged. There are many
other features in the other bits of this register.
With later revisions of Intel's Pentium 4 line, they extended SSE2 a bit further.
AMD Athlon64's are supposed to support these instructions as well.
These new instructions are known as SSE3 or Prescott New
Please note that SSE extends the way the cpu operates, so not only
does the CPU have to support it, but the OS
also needs to support it.
The way to detect this varies from system to system.
Windows98 and up support SSE
Linux 2.4 supports SSE (patches for 2.2, if it's not native by now)
flavors have support for SSE as well.
With the above information in hand, detecting available SIMD extensions
should be simple.