c++assemblydriverkmdfcpuid

Reading asm cpuid directly


How I can read this instruction directly:

unsigned int eax, ebx, ecx, edx;
unsigned int leaf, subleaf;
unsigned int  intbuf[12];`
char *buffer;
int i,j,k,base,start,stop,length;
float freq_GHz;
float frequency;

subleaf=0;

base = 0;
for (leaf=0x80000002; leaf<0x80000005; leaf++) {
    
    __asm__ __volatile__ ("cpuid" : \
      "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (leaf), "c" (subleaf));


    intbuf[base] = eax;
    intbuf[base+1] = ebx;
    intbuf[base+2] = ecx;
    intbuf[base+3] = edx;
    base += 4;
}

I've been trying to read it like this but its not working:

for (leaf = 0x80000002; leaf < 0x80000005; leaf++) {
        
        int regs[4];
        __cpuid(regs, leaf);
        
        intbuf[base] = (*regs),eax;
            intbuf[base + 1] = (*regs),ebx;
            intbuf[base + 2] = (*regs),ecx;
            intbuf[base + 3] = (*regs),edx;
        base += 4;

Solution

  • The regs array that you pass to the __cpuid call1 will, on return, have the values of the four registers, EAX, EBX, ECX and EDX, in order (i.e. in the array elements, regs[0] thru regs[3]). You access those elements using normal array operators, and there is no need for any temporary 'register' variables like your eax.

    Thus, your 'pure' C++ code would look something like this:

    int intbuf[12];
    int base = 0;
    for (leaf = 0x80000002; leaf < 0x80000005; leaf++)
    {        
        int regs[4];
        __cpuid(regs, leaf);    
        intbuf[base] = regs[0];     // EAX
        intbuf[base + 1] = regs[1]; // EBX
        intbuf[base + 2] = regs[2]; // ECX
        intbuf[base + 3] = regs[3]; // EDX
        base += 4;
    }
    

    If you want to keep intbuf as an array of unsigned int, then you should add a cast to the assignments inside the loop, like:

    //...
        intbuf[base + 1] = static_cast<unsigned int>(regs[1]); // EBX
    

    1 This answer is based on the operation of the MSVC implementation of the __cpuid function; other compilers' versions may differ slightly but the general principle will likely remain the same.