delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/04/15/16:10:51

From: buers AT gmx DOT de (Dieter Buerssner)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: CPUID Opcode
Date: 15 Apr 2000 20:21:29 GMT
Lines: 104
Message-ID: <8daq3o.3vs7iub.0@buerssner-17104.user.cis.dfn.de>
References: <38F8B55B DOT 5BFDA8E0 AT home DOT com>
NNTP-Posting-Host: pec-90-244.tnt4.s2.uunet.de (149.225.90.244)
Mime-Version: 1.0
X-Trace: fu-berlin.de 955830089 7857270 149.225.90.244 (16 [17104])
X-Posting-Agent: Hamster/1.3.13.0
User-Agent: Xnews/03.02.04
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Robin Johnson wrote:

>source:

Your source didn't compile here. 

>#include <stdio.h>

You don't need the next line, but this has nothing to do with
your problem.

>#include <iostream.h>
>#include <string.h>
>
>typedef long longreg;

The longreg won't buy you much, when you use it in the get_cpuid
function only, but not in the caller. Also, I would tend to make
it unsigned long.

You won't need the next line anymore.

>typedef char chars[4];
>
>void get_cpuid(const long int cpuidval, longreg &r_eax, longreg &r_ebx, 
>               longreg &r_ecx, longreg &r_edx)
>{ __asm__ __volatile__
>  (     " pushl %%eax\n pushl %%ebx\n pushl %%ecx\n pushl %%edx\n
>          movl %4, %%eax     \n
>          cpuid      \n
>       movl %%eax, %0     \n
>         movl %%ebx, %1     \n
>         movl %%ecx, %2     \n
>         movl %%edx, %3     \n
>          popl %%edx\n popl %%ecx\n popl %%ebx\n popl %%eax"
>   :     "=g" (r_eax), "=g" (r_ebx), "=g" (r_ecx), "=g" (r_edx)
>   : "g" (cpuidval)
>   : "ax", "bx", "cx", "dx", "memory"
>   );

Here I get the infamous "spilled register" error. I can't really
say why. This might even be a bug in gcc. Any comments?

Note, that the pushs and pops are not necessary, when
the registers are already in the clobber-list. Also, the "memory"
is not needed here.

Anyway, the (at least to me) more obvious code

  __asm__ __volatile__(
    "cpuid"
    : "=a" (r_eax), "=b" (r_ebx), "=c" (r_ecx), "=d" (r_edx)
    : "0" (cpuidval));

works here.

> }
>
>void main()

You should use 

int main(void) 

here.

>{ long int a,b,c,d;
>  char nb[4],nc[4],nd[4];
>  printf("cpuid\n");
>  get_cpuid(0,a,b,c,d);
>  memcpy(nb,b,4);
>  memcpy(nc,c,4);
>  memcpy(nd,d,4);
>  printf("Max EAX: %i\nName: %s%s%s\n",a,nb,nc,nd);
> }

This has a few errors (and won't even compile here).
Instead of memcpy(nb, b, 4) you would need to use memcpy(nb, &b, 4)
or even memcpy(nb, &b, sizeof b). But this would still not work,
because the nb would not be zero terminated, so you must not printf it
with %s. Also "%i" should not be used with long int. Using gcc -Wall
should warn you about this.

Any decent book on C or C++ should explain these points.

The following code works:

int main(void)
{ 
  long int a,b,c,d;
  char buf[13];
  printf("cpuid\n");
  get_cpuid(0,a,b,c,d);
  // Copy all the bits together
  memcpy(buf, &b, 4);
  memcpy(buf+4, &d, 4);
  memcpy(buf+8, &c, 4);
  buf[12] = '\0'; // zero terminate the string 
  printf("Max EAX: %ld\nName: %s\n", a, buf);
  return 0;
}

-- 
Regards, Dieter

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019