Page 2 of 2

Re: here are cpuid with raw output

Posted: Mon Mar 12, 2018 1:30 pm
by ggodw000
Octocontrabass wrote:
ggodw000 wrote:I wondered if there is a way to fit all the series of instructions in one asm() call making it atomic.
Of course there is. You can put as many instructions in a single asm() call as you want.

But, for CPUID, you don't need more than one instruction. If you use the correct input and output constraints, GCC will automatically generate the instructions to load EAX before CPUID and read the outputs afterwards.

In fact, I already showed you one possible way to write it.

Code: Select all

asm( "cpuid" : "=a"(eax_value), "=b"(ebx_value), "=c"(ecx_value), "=d"(edx_value) : "a"(leaf) );
Reviving the long lost thread, looking at extended asm section of this doc: https://gcc.gnu.org/onlinedocs/gcc/Exte ... tended-Asm, it looks like it fits into the call convention:

Code: Select all

asm [volatile] ( AssemblerTemplate 
                 : OutputOperands 
                 [ : InputOperands
                 [ : Clobbers ] ])
With that, it appears cpuid is

Code: Select all

assembler template
, output operands are

Code: Select all

"=a"(eax_value), "=b"(ebx_value), "=c"(ecx_value), "=d"(edx_value)
: and inputs operands are "

Code: Select all

a"(leaf)
, correct?
Once executed, the variable (possibly long int) a, b, c and d will hold the result of CPUID which can safely be used.
thx.

Re: here are cpuid with raw output

Posted: Mon Mar 12, 2018 1:43 pm
by ggodw000
Oh wait, what is a, b, c and d in this case?
I had to declare all of 'em for the compilation to work.
I can see eax_value through edx_value will hold the return values.

Code: Select all

    int a, b, c, d;
    int eax_value, ebx_value, ecx_value, edx_value, leaf;

        printf("\neax_value: %08x", eax_value);
        printf("\nebx_value: %08x", ebx_value);
        printf("\necx_value: %08x", ecx_value);
        printf("\nedx_value: %08x", edx_value);
result:

Code: Select all

Issuing CPUID 0
eax_value: 00000014
ebx_value: 756e6547
ecx_value: 6c65746e
edx_value: 49656e69
----------------------------
Issuing CPUID 1
eax_value: 000406f1
ebx_value: 01040800
ecx_value: 9ed83203
edx_value: 1fabfbff
----------------------------
Issuing CPUID 2
eax_value: 76036301
ebx_value: 00f0b5ff
ecx_value: 00000000
edx_value: 00c30000
----------------------------
Issuing CPUID 3
eax_value: 00000000
ebx_value: 00000000
ecx_value: 00000000
edx_value: 00000000
Done.

Re: here are cpuid with raw output

Posted: Tue Mar 13, 2018 10:17 am
by Octocontrabass
ggodw000 wrote:Oh wait, what is a, b, c and d in this case?
The strings "=a", "=b", "=c", "=d", and "a" in the inline assembly are the constraints. The "=" portion is a modifier that indicates an operand that will be written to by the assembly code. The four letters "a", "b", "c", and "d" are specific to the target CPU, and on x86 they indicate that the operand may be placed in EAX, EBX, ECX, or EDX respectively.
ggodw000 wrote:I had to declare all of 'em for the compilation to work.

Code: Select all

    int a, b, c, d;
You don't have to declare those. Only the expression in the parentheses needs to be declared in the surrounding C code.

Re: here are cpuid with raw output

Posted: Tue Mar 13, 2018 4:55 pm
by ggodw000
Octocontrabass wrote:
ggodw000 wrote:Oh wait, what is a, b, c and d in this case?
The strings "=a", "=b", "=c", "=d", and "a" in the inline assembly are the constraints. The "=" portion is a modifier that indicates an operand that will be written to by the assembly code. The four letters "a", "b", "c", and "d" are specific to the target CPU, and on x86 they indicate that the operand may be placed in EAX, EBX, ECX, or EDX respectively.
ggodw000 wrote:I had to declare all of 'em for the compilation to work.

Code: Select all

    int a, b, c, d;
You don't have to declare those. Only the expression in the parentheses needs to be declared in the surrounding C code.
yes that was not necessary.