Can't get CPU vendor

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
deleted8917
Member
Member
Posts: 119
Joined: Wed Dec 12, 2018 12:16 pm

Can't get CPU vendor

Post by deleted8917 »

I have this inline ASM function, that should return the CPU vendor:

Code: Select all

void printvendor(void)
{
    /* This file (cpu.c) is compiled using -masm=intel */
   asm volatile("mov eax, 0\t\n"
                "cpuid\t\n"
                "mov dword [vendor], ebx\n\t"
                "mov dword [vendor+4], edx\n\t"
                "mov dword [vendor+8], ecx\n\t");
   println(vendor);
}
As the comment says, cpu.c is compilled under -masm=intel
I call the function, but nothing gets printed. Any idea?
thanks
Octocontrabass
Member
Member
Posts: 5586
Joined: Mon Mar 25, 2013 7:01 pm

Re: Can't get CPU vendor

Post by Octocontrabass »

Your inline assembly claims to have no side effects, so GCC doesn't know that you're clobbering four registers and modifying some memory.

You're also accessing a (global?) variable from inline assembly, which is discouraged since GCC's optimizations may not refer to said variable in ways you expect.

GCC provides cpuid.h which is recommended instead of using inline assembly. If you still want to use inline assembly, you can look at cpuid.h for an example of how to do it.
deleted8917
Member
Member
Posts: 119
Joined: Wed Dec 12, 2018 12:16 pm

Re: Can't get CPU vendor

Post by deleted8917 »

I know that cpuid.h exists, but I have no idea how to use it.
btw, GCC inline ASM is so complex, and weird...
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Can't get CPU vendor

Post by bzt »

hextakatt wrote:I know that cpuid.h exists, but I have no idea how to use it.
btw, GCC inline ASM is so complex, and weird...
If you're not familiar with inline asm, using cpuid.h seems pretty straightforward to me.

Code: Select all

#include <cpuid.h>

unsigned int eaxvar, ebxvar, ecxvar, edxvar;
__get_cpuid(0, &eaxvar, &ebxvar, &ecxvar, &edxvar);
Simple. Or, in your case more like

Code: Select all

unsigned char vendor[13];
memset(vendor, 0, sizeof(vendor));
__get_cpuid(0, &eaxvar, &vendor[0], &vendor[8], &vendor[4]);
println(vendor);
The cpuid.h defines exactly the inline asm you're looking for, which btw also answers your original question. Not that complex or weird as you may think.

Code: Select all

#define __cpuid(level, a, b, c, d)			\
  __asm__ ("cpuid\n\t"					\
	   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)	\
: "0" (level))
The "0" passes the level in eax as input (the hidden %%0 parameter in the template), and the ouput is saved in a=eax ("=a" refers to eax), b=ebx ("=b" refers to ebx), etc.

Cheers,
bzt
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Can't get CPU vendor

Post by iansjack »

If you find inline assembler confusing (and I tend to agree with you), write the function in pure assembler and link it into your final program.
deleted8917
Member
Member
Posts: 119
Joined: Wed Dec 12, 2018 12:16 pm

Re: Can't get CPU vendor

Post by deleted8917 »

bzt wrote:
hextakatt wrote:I know that cpuid.h exists, but I have no idea how to use it.
btw, GCC inline ASM is so complex, and weird...
If you're not familiar with inline asm, using cpuid.h seems pretty straightforward to me.

Code: Select all

#include <cpuid.h>

unsigned int eaxvar, ebxvar, ecxvar, edxvar;
__get_cpuid(0, &eaxvar, &ebxvar, &ecxvar, &edxvar);
Simple. Or, in your case more like

Code: Select all

unsigned char vendor[13];
memset(vendor, 0, sizeof(vendor));
__get_cpuid(0, &eaxvar, &vendor[0], &vendor[8], &vendor[4]);
println(vendor);
The cpuid.h defines exactly the inline asm you're looking for, which btw also answers your original question. Not that complex or weird as you may think.

Code: Select all

#define __cpuid(level, a, b, c, d)			\
  __asm__ ("cpuid\n\t"					\
	   : "=a" (a), "=b" (b), "=c" (c), "=d" (d)	\
: "0" (level))
The "0" passes the level in eax as input (the hidden %%0 parameter in the template), and the ouput is saved in a=eax ("=a" refers to eax), b=ebx ("=b" refers to ebx), etc.

Cheers,
bzt
Thanks! I hadn't found a way to use it!
iansjack wrote:If you find inline assembler confusing (and I tend to agree with you), write the function in pure assembler and link it into your final program.
Yes, GCC inline ASM is kinda weird and complex for me (at least). As you suggest in your reply, yes I tried to make the function in pure ASM, and then link it, but I couldn't make it work.
Thanks.
Post Reply