🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

inline assembly code in c++???

Started by
15 comments, last by avianRR 22 years, 11 months ago
Now that I''ve got all my header files I need to know how to convert some code. This is what I''m useing under windows, I need to convert it to something that can compile under linux... __asm{ // cli pushfd pop eax mov ebx,eax xor eax, 0x00200000 push eax popfd pushfd pop eax // sti cmp eax,ebx jz NO_CPUID mov [CPUID_AVAILABLE] , 0x01 NO_CPUID: } I''ve tryed... asm pushfd asm pop eax asm mov ebx,eax asm xor eax,0x00200000 asm push eax asm popfd asm pushfd asm pop eax asm cmp eax,ebx asm jz NO_CPUID asm mov [CPUID_AVAILABLE], 0x01 asm NO_CPUID: and... asm{ pushfd pop eax mov ebx,eax xor eax,0x00200000 push eax popfd pushfd pop eax cmp eax,ebx jz NO_CPUID mov [CPUID_AVAILABLE], 0x01 NO_CPUID: } I even tryed replacing asm with _asm or __asm and I keep getting parse errors, any help would be appreciated...
------------------------------Piggies, I need more piggies![pig][pig][pig][pig][pig][pig]------------------------------Do not invoke the wrath of the Irken elite. [flaming]
Advertisement
Assuming you''re using GCC...

Inline ASM with GCC is *very* different from VC++. Be prepared for statements like:
  asm("cld\n\t"     "rep\n\t"     "stosl"     :      : "c" (someVar), "a" (someOtherVar), "D" (extraVar)     : "%ecx", "%edi");  

I would recommend checking out this article: http://www.linux.org/docs/ldp/howto/Assembly-HOWTO/gcc.html.

~~~~~~~~~~
Martee
ReactOS - an Open-source operating system compatible with Windows NT apps and drivers
As Martee has pointed out, GCC inline assembly is a different world from MSVC++. GCC uses GAS (the GNU Assembler) as its assembler, which employs a rather different syntax. His pointer to the Linux Documentation Project is the place to go for all the details.

Good luck!
I just had to ask: is it imperative that you use assembly? Since I gather you''re just getting used to development under Linux, perhaps you might want to concentrate on C/C++ (or your language of preference) for now. Unless you really need to write low-level code, perhaps you should save your optimizations until your software as a whole is fully functional under Linux?

Just a thought.
ok, that still hasn''t helped I still get the same errors...

gcc -Wall -c System.cpp
System.cpp: In method ''void SYSTEM::InterogateCPU()''"
System.cpp:102: parse error before ''{''
System.cpp:82: warning unused variable ''char CPUID_AVAILABLE''
Ssytem.cpp: At top level:

void SYSTEM::InterogateCPU(){
char CPUID_AVAILABLE = 0; //<<<<<<<<<<this is line 82
// Test to see if cpuid is available
#ifdef _WIN32
__asm{
// cli
pushfd
pop eax
mov ebx,eax
xor eax, 0x00200000
push eax
popfd
pushfd
pop eax
// sti
cmp eax,ebx
jz NO_CPUID
mov [CPUID_AVAILABLE] , 0x01
NO_CPUID:
}
#elif __linux__
asm{ // <<<<<<<<<this is line 102
pushfd
pop %eax
mov %eax,%ebx
xor $0x00200000,%eax
push %eax
popfd
pushfd
pop %eax
cmp %ebx,%eax
jz NO_CPUID
mov $0x01,CPUID_AVAILABLE
NO_CPUID:
}
#else
CPUID_AVAILABLE = 0;
#endif
if(!CPUID_AVAILABLE)
return;


For the most part I''ve been able to get most of my program to compile now as it''s mostly ansi c/c++. However there are a few parts such as this that I''m having trouble with. What this function does is interogate the cpuid function to determine what features are available. This code snippit is the first part of the function that determins if the cpuid function is available and if not returns leaving the cpu data contining some default flags indicating that all info is unknown. This is the only place I have assembly language code and it''s just anoying the heck out of me that I can''t get it to work!
------------------------------Piggies, I need more piggies![pig][pig][pig][pig][pig][pig]------------------------------Do not invoke the wrath of the Irken elite. [flaming]
quote: Original post by Oluseyi
I just had to ask: is it imperative that you use assembly?

Yes, unless you know another way to call the cpuid function.

quote: Original post by Oluseyi
Since I gather you''re just getting used to development under Linux, perhaps you might want to concentrate on C/C++ (or your language of preference) for now. Unless you really need to write low-level code, perhaps you should save your optimizations until your software as a whole is fully functional under Linux?

Just a thought.


My thought too. This one function could be completly bypassed in linux and one or two other minor changes made and the program should still work. On the other hand I want this to function work!
------------------------------Piggies, I need more piggies![pig][pig][pig][pig][pig][pig]------------------------------Do not invoke the wrath of the Irken elite. [flaming]
Head over to linuxassembly.org, they might have some info you want.

Also, don''t you need a ; after the asm{} thing? I''m not sure because I do my asm in nasm then link the .o files.
Head over to linuxassembly.org, they might have some info you want.

Also, don''t you need a ; after the asm{} thing? I''m not sure because I do my asm in nasm then link the .o files.
quote: Original post by gph-gw
Head over to linuxassembly.org, they might have some info you want.

Also, don''t you need a ; after the asm{} thing? I''m not sure because I do my asm in nasm then link the .o files.


Great link, I''ve almost got it all working now. And yes it needed a semicolon and it was also supposed to be () and not {} pluss the asm needed double underlines before AND after it __asm__
I''ve now got almost all the assembly code compiling. I just have two more problems if you (or anyone) can help me figure it out...

the first is I have to push and pop the eflags register (pushfd, popfd) I can''t however find the equivelant operation under linux and they come up with the warning "no such 386 instruction"

example...
"pushfd\n\t"
produces the error "/tmp/ccjs1zp.s: 305: no such 386 instruction: ''pushfd''"

the next problem I have is durring linking. I have to access several C variables and I end up with the errors "undefined reference to ''variable name''" but it compiled fine.

example...
int info = 0;
__asm__(
"mov $0x01,%eax\n\t"
"cpuid\n\t"
"mov $info,%eax\n\t"
);
then I get the error "System.o(.text+0x30a): undefined reference to ''info''" durring linking

I''ll keep working on it myself but if anyone has any tips please let me know,
thx,
------------------------------Piggies, I need more piggies![pig][pig][pig][pig][pig][pig]------------------------------Do not invoke the wrath of the Irken elite. [flaming]
You can''t directly use variables in inline ASM. I think this might do what you''re looking for:

int info = 0;
__asm__(
"mov $0x01,%eax\n\t"
"cpuid\n\t"
:"=a"(info)
);



~~~~~~~~~~
Martee
ReactOS - an Open-source operating system compatible with Windows NT apps and drivers

This topic is closed to new replies.

Advertisement