OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 8:31 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Can't get CPU vendor
PostPosted: Wed Feb 06, 2019 9:51 pm 
Offline
Member
Member

Joined: Wed Dec 12, 2018 12:16 pm
Posts: 119
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


Top
 Profile  
 
 Post subject: Re: Can't get CPU vendor
PostPosted: Thu Feb 07, 2019 8:41 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
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.


Top
 Profile  
 
 Post subject: Re: Can't get CPU vendor
PostPosted: Thu Feb 07, 2019 9:46 am 
Offline
Member
Member

Joined: Wed Dec 12, 2018 12:16 pm
Posts: 119
I know that cpuid.h exists, but I have no idea how to use it.
btw, GCC inline ASM is so complex, and weird...


Top
 Profile  
 
 Post subject: Re: Can't get CPU vendor
PostPosted: Thu Feb 07, 2019 12:20 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 1584
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


Top
 Profile  
 
 Post subject: Re: Can't get CPU vendor
PostPosted: Thu Feb 07, 2019 1:01 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
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.


Top
 Profile  
 
 Post subject: Re: Can't get CPU vendor
PostPosted: Thu Feb 07, 2019 6:32 pm 
Offline
Member
Member

Joined: Wed Dec 12, 2018 12:16 pm
Posts: 119
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], SemrushBot [Bot] and 68 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group