OSDev.org
https://forum.osdev.org/

Can't get CPU vendor
https://forum.osdev.org/viewtopic.php?f=1&t=33489
Page 1 of 1

Author:  hextakatt [ Wed Feb 06, 2019 9:51 pm ]
Post subject:  Can't get CPU vendor

I have this inline ASM function, that should return the CPU vendor:
Code:
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

Author:  Octocontrabass [ Thu Feb 07, 2019 8:41 am ]
Post subject:  Re: Can't get CPU vendor

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.

Author:  hextakatt [ Thu Feb 07, 2019 9:46 am ]
Post subject:  Re: Can't get CPU vendor

I know that cpuid.h exists, but I have no idea how to use it.
btw, GCC inline ASM is so complex, and weird...

Author:  bzt [ Thu Feb 07, 2019 12:20 pm ]
Post subject:  Re: Can't get CPU vendor

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:
#include <cpuid.h>

unsigned int eaxvar, ebxvar, ecxvar, edxvar;
__get_cpuid(0, &eaxvar, &ebxvar, &ecxvar, &edxvar);
Simple. Or, in your case more like
Code:
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:
#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

Author:  iansjack [ Thu Feb 07, 2019 1:01 pm ]
Post subject:  Re: Can't get CPU vendor

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.

Author:  hextakatt [ Thu Feb 07, 2019 6:32 pm ]
Post subject:  Re: Can't get CPU vendor

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:
#include <cpuid.h>

unsigned int eaxvar, ebxvar, ecxvar, edxvar;
__get_cpuid(0, &eaxvar, &ebxvar, &ecxvar, &edxvar);
Simple. Or, in your case more like
Code:
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:
#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.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/