Need some ASM/C advice
Need some ASM/C advice
For some reason I decided it would be neat to write a little library on my own that would simplify access to CPUID provided by Intel. I started looking at the Intel documentation which included both assembly and C code.
In the document Intel provides some assembly examples on how to do this. Long story short, after some frustration I gave up on the hopes of assembling the code. Plus it's copyrighted by Intel so call me paranoid, but...
Which brought me to my question. I have some options here. The first is to write the helper functions in assembly, write a C header file that prototypes the functions and then just assemble the files then link them together with C code. If I was smart, I could do most of the tedious processing in C and only use the assembly portions where required. Which lead me to my second option, why not use inline assembly in my C code to begin with. Is this simply a question of style?
What are you all's thoughts. Am I completely wasting my time?
In the document Intel provides some assembly examples on how to do this. Long story short, after some frustration I gave up on the hopes of assembling the code. Plus it's copyrighted by Intel so call me paranoid, but...
Which brought me to my question. I have some options here. The first is to write the helper functions in assembly, write a C header file that prototypes the functions and then just assemble the files then link them together with C code. If I was smart, I could do most of the tedious processing in C and only use the assembly portions where required. Which lead me to my second option, why not use inline assembly in my C code to begin with. Is this simply a question of style?
What are you all's thoughts. Am I completely wasting my time?
Thanks for all the fish.
hi, I've written a CPUID library in C with inline asm. I didn't run into many issues at all, and (because I'm more familiar with C) found it to not be all that hard either.
I made an array of known CPU properties (sse, mmx, etc..) and enumerated them that way.
It's completely up to you and what you feel comfortable doing though, if you are better at ASM, Id suggest doing it in ASM, if you're better in C, do it in C, just make sure you know the proper __asm(""); format and to clobber what needs to be destroyed in the end.
I made an array of known CPU properties (sse, mmx, etc..) and enumerated them that way.
It's completely up to you and what you feel comfortable doing though, if you are better at ASM, Id suggest doing it in ASM, if you're better in C, do it in C, just make sure you know the proper __asm(""); format and to clobber what needs to be destroyed in the end.
Website: https://joscor.com
Mostly a matter of style, yes. Inline assembly makes your code compiler-specific, as there is no standard way to do it. So splitting it up into a C file and a ASM file seems "cleaner" to some (me included). But since ASM code is assembler-specific anyhow, it's in the eye of the beholder.
Every good solution is obvious once you've found it.
-
- Member
- Posts: 566
- Joined: Tue Jun 20, 2006 9:17 am
Hope this upload helps ...
Hope this link helps ...
http://www.advancedlinuxprogramming.com ... ne-asm.pdf
http://www.advancedlinuxprogramming.com ... ne-asm.pdf
Thanks for the input everyone. I played around with the approach of using inline assembly. Here's what I wrote.
The code compiles, but when executing I get a segmentation fault (wonderful). I started up gdb and found it was coming from __vfprintf. So I commented out printf and it ran fine. Well, I assume it ran fine because obviously I got no output to the screen. My current path of thinking leads me to believe that printf is using eax. So then I tried to add eax to the clobber list thinking that would do the trick. When I do that, I can't get the dang thing to compile! Here's what I had:
My gcc error says:
Thanks.
Code: Select all
#include <stdio.h>
int main(void)
{
int foo = 0;
__asm__ __volatile__(
"movl $0x00,%%eax\n\t" /* load 00h into eas */ \
"cpuid\n\t" /* execute cpuid */ \
:"=a"(foo) /* output to foo */
: /* no input registers */
);
printf("result: %d\n",foo);
return 0;
}
Code: Select all
#include <stdio.h>
int main(void)
{
int foo = 0;
__asm__ __volatile__(
"movl $0x00,%%eax\n\t" /* load 00h into eas */ \
"cpuid\n\t" /* execute cpuid */ \
:"=a"(foo) /* output to foo */
: /* no input registers */
:"%%eax" /* clobber the stinker */
);
printf("result: %d\n",foo);
return 0;
}
Any help/comments would be appreciated.2.c: In function ‘main’:
2.c:7: error: unknown register name ‘%%eax’ in ‘asm’
Thanks.
Thanks for all the fish.
After some more exploring, I think I got it.
After a brief moment of clarity, I remembered CPUID outputs to eax, ebx, ecx, and edx. So I named those as outputs. Then I had the problem of ebx can't be jacked with. Something about PIC or whatever. So I added some code to push the value of ebx onto the stack and then call CPUID, save the resulting ebx to a different register then restore the original ebx value from the stack.
There are finally some values in my variables. Need to make sure they're what I expected, though.
Code: Select all
#include <stdio.h>
int main(void)
{
int a,b,c,d;
asm(
"pushl %%ebx\n\t" /* need to store off ebx */\
"movl $0x00,%%eax\n\t" /* load 00h into eas */ \
"cpuid\n\t" /* execute cpuid */ \
"movl %%ebx, %%esi\n\t" /* move ebx value to another register */\
"popl %%ebx\n" /* restore the ebx value */
:"=a"(a),"=S"(b),"=c"(c),"=d"(d) /* output */
: /* no input registers */
);
printf("a: %d, b: %d, c: %d, d: %d\n",a,b,c,d);
return 0;
}
There are finally some values in my variables. Need to make sure they're what I expected, though.
Thanks for all the fish.
- piranha
- Member
- Posts: 1391
- Joined: Thu Dec 21, 2006 7:42 pm
- Location: Unknown. Momentum is pretty certain, however.
- Contact:
Heh heh.......Paranoid!Plus it's copyrighted by Intel so call me paranoid, but...
-JL
P.S. I'm bored.
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io