Page 1 of 1
inline ASM problem
Posted: Fri Feb 28, 2003 8:50 pm
by stonedzealot
In accordance with my last topic (RAM/CPU info) I started to try and implement CPU detection. I created this inline ASM function:
Code: Select all
void getcpufamily()
{
char VendorSign[13];
unsigned long MaxEAX;
printmessage("START", 10, 10, 0x02);
__asm__ __volatile__( //<--LINE 52
"movl 0,%%EAX\n"
"cpuid\n"
"movl %%EBX, %0\n"
"movl %%EDX,4(%0)\n"
"movl %%ECX,8(%0)\n"
"movl %%EAX,%1"
: "=g" (VendorSign)
);
VendorSign[12] = 0;
printmessage("END", 10, 11, 0x02);
printmessage(VendorSign, 0, 2, 0x02);
}
I don't think it's the code, but I thought I should give some background. Anway, GCC gives the error:
io.c:52: invalid `asm' : operand number out of range.
What is that?! I have no clue. I marked the line it says it's giving the error on in the code. Can someone help me out?
Re:inline ASM problem
Posted: Sat Mar 01, 2003 5:45 am
by richie
I'm not very familiar with the AT&T syntax but I think the mistake is one line later. 0 is a constant value and I think in the AT&T syntax you have to use a Dollarsign before each constant. Try if this code works:
Code: Select all
void getcpufamily()
{
char VendorSign[13];
unsigned long MaxEAX;
printmessage("START", 10, 10, 0x02);
__asm__ __volatile__(
"movl $0,%%EAX\n"
"cpuid\n"
"movl %%EBX, %0\n"
"movl %%EDX,4(%0)\n"
"movl %%ECX,8(%0)\n"
"movl %%EAX,%1"
: "=g" (VendorSign)
);
VendorSign[12] = 0;
printmessage("END", 10, 11, 0x02);
printmessage(VendorSign, 0, 2, 0x02);
}
But as I already has said: I don't know very much about AT&T. But testing this is better than doing nothing.
Re:inline ASM problem
Posted: Sat Mar 01, 2003 9:22 am
by Pype.Clicker
the problem comes from your %1 command: you're asking gcc the second argument but you only provide one (%0)
Re:inline ASM problem
Posted: Sat Mar 01, 2003 10:38 am
by stonedzealot
D'OH! OH man, I can't believe that. Agh, as I've mentioned before, sometimes I miss the obvious stuff.
btw, it should be 4%0 and 8%0 not 4(%0) and 8(%0)
I guess it's different from AT&T
Re:inline ASM problem
Posted: Mon Mar 17, 2003 10:08 am
by Scalpel
I tried your code here, with %1 changed to %0, and with the 4%0 and 8%0 corrections, but when I print the string I get just one ASCII character out. It was the white smileyface at position 0,1 in
this chart
I tried it in both Bochs and on my Pentium III 1GHz, but the same output. Did you get it to work properly?
Re:inline ASM problem
Posted: Mon Mar 17, 2003 1:44 pm
by stonedzealot
Well, I got the inline ASM problem worked out as above, but the CPUID code I had I dropped because I needed to go back and gain a better understanding of what was being done earlier in my kernel. Therefore I sorta scrapped and am rebuliding the kernel. I can, however, give you a nice place for the CPUID function....
http://osdev.berlios.de/cpuid.html
Quite a nice place, I think.
Re:inline ASM problem
Posted: Wed Mar 19, 2003 4:04 am
by surya4friends
Well this should be code!
#include <stdio.h>
void DetectCPUFamily()
{
char strCompany[13];
unsigned long MaxEAX;
__asm__ __volatile__(
"cld\n\t"
"cpuid\n\t"
"movl %%EBX,%0\n\t"
"movl %%EDX,4%0\n\t"
"movl %%ECX,8%0\n\t"
"movl %%EAX,%1\n\t"
: "=g"(strCompany)
: "a" (0)
);
strCompany[12] = 0;
printf(strCompany);
}
int main(void)
{
printf("CPU Family detector v0.0.1\n\nCPU Type:\t");
DetectCPUFamily();
}
To compile:
gcc -c FILENAME.C
Link and make exe:
gcc -o EXENAME FILENAME.O
About putting 1 in %eax, or 2, as intial value, here is what intel maual 2 says,
Initial Information Provided about the Processor
EAX
Value
0 EAX-Maximum CPUID Input Value (2 for the P6
family processors and 1 for the Pentium ?
processor and the later versions of Intel486?
processor that support the CPUID instruction).
EBX-"Genu"
ECX-"ntel"
EDX-"ineI"
1 EAX- Version Information (Type, Family, Model, and
Stepping ID)
EBX- Reserved
ECX- Reserved
EDX- Feature Information
2 EAX- Cache and TLB Information
EBX- Cache and TLB Information
ECX- Cache and TLB Information
EDX- Cache and TLB Information
See pg 3-111 ( as per Acrobat viewer - Page 151) of Intel Architecture Software Developer?s Manual Volume 2:Instruction Set Reference.
Re:inline ASM problem
Posted: Wed Mar 19, 2003 4:33 am
by Pype.Clicker
there's something that seems weird in the manner you give the access to VendorString, imho. i would rather try
Code: Select all
asm(..."mov %%ebx,$0; mov %%ecx,$1; mov %%edx,$2": "=g"(VendorString),"=g"(VendorString+4),"=g"(VendorString+8)
BTW, use objdump -d or ndisasm to check the generated code is the one you wish.
another option would be
Code: Select all
asm("cpuid":"=a"(max_eax),"=b"(VendorString),
"=c"(VendorString+4),"=d"(VendorString+8):"0"(0))
Re:inline ASM problem
Posted: Wed Mar 19, 2003 10:15 am
by Scalpel
Code: Select all
void getcpufamily()
{
char VendorString[13];
unsigned long MaxEAX;
sprintf("\ngetcpufamily start",0);
__asm__ __volatile__ (
"cld\n"
"cpuid\n"
"movl %%ebx, $1\n"
"movl %%edx, $2\n"
"movl %%ecx, $3\n"
"movl %%eax,%0"
: "=g" (VendorString), "=g"(VendorString+4),"=g"(VendorString+8)
);
VendorString[12]=0;
sprintf("\ngetcpufamily end. String is: ",0);
sprintf(VendorString,0);
}
I tried this code, but get the error 'invalid lvalue in assignment'.
Re:inline ASM problem
Posted: Wed Mar 19, 2003 10:31 pm
by surya4friends
Hey Pype.Clicker,
Thanks for suggestion for using objdump / ndiasmw. Never came to my mind.
Well other than that my question is can I use NASM for Windows for OS developement? or should I use DJGPP ? I am using DJGPP GCC for OS. is there any clear and distinct advantage for choosing one over another? any links or pointers welcome!
Thanks!
BTW, code you mentioned give compile time error to me too!
Re:inline ASM problem
Posted: Thu Apr 24, 2003 10:52 am
by Jonathan
Hmm I didn't get the first code to compile either so I made som small changes to it. This works with gcc >3.x.
Code: Select all
#include <stdio.h>
void DetectCPUFamily()
{
char strCompany[13];
/*unsigned long MaxEAX;*/
asm volatile(
"cld\n\t"
"cpuid\n\t"
"movl %%EBX,%0\n\t"
"movl %%EDX,4%0\n\t"
"movl %%ECX,8%0\n\t"
"movl %%EAX,%1\n\t"
: "=g"(strCompany)
: "a" (0)
);
strCompany[12] = 0;
printf(strCompany);
}
int main(void)
{
printf("CPU Family detector v0.0.1\n\nCPU Type:\t");
DetectCPUFamily();
return 0;
}