Inconsistent CPUID results with different callers for some EAX values

111 views Asked by At
unsigned int a, b;
a = 0;
b = 0;

for(a=0; a<6; a++)
{
    __asm__("cpuid"
        :"=a"(b)                 /** EAX into b (output) */
        :"0"(a)                  /** a into EAX (input) */
        :"%ebx","%ecx","%edx");  /** clobbered registers */
    printf("a=%d, b=0x%x", a, b);
}

Above code prints value of a and b.

In Ubuntu 22, this portion of code I am using for 2 projects. One is quite small one and other is bigger one. I see values of a and b are printed in small and big projects as below.

a, b values in small project

a=0, b=0x20
a=1, b=0xb06a3
a=2, b=0xfeff01
a=3, b=0x0
a=4, b=0x0
a=5, b=0x40
a=6, b=0xdf8ff7

a, b values in bigger project

a=0, b=0x20
a=1, b=0xb06a3
a=2, b=0xfeff01
a=3, b=0x0
a=4, b=0x7c01c143
a=5, b=0x40
a=6, b=0xdf8ff7

You can see in line starting with a=4, b value is different for above two cases. I am surprised why values becoming different, ideally values should remain same even if this code is run from different projects.

Can somebody please help me to understand how come values are different.

1

There are 1 answers

5
teapot418 On BEST ANSWER

https://www.felixcloutier.com/x86/cpuid

4 is Deterministic Cache Parameters Leaf

Information returned depends on the value in ECX. A 0 result means that ECX did not contain the index of a valid cache.

Try setting ECX to the same value for both and the results should stabilize as well.

Example:

__asm__("movl $0,%%ecx;\n\t"
        "cpuid"
    :"=a"(b)                 /** EAX into b (output) */
    :"0"(a)                  /** a into EAX (input) */
    :"%ebx","%ecx","%edx");  /** clobbered registers */