flat assembler
Message board for the users of flat assembler.

Index > Main > Problem regarding AT&T sintax on GCC inline assembly

Author
Thread Post new topic Reply to topic
Cthulhu



Joined: 12 May 2005
Posts: 29
Cthulhu 15 Sep 2008, 20:35
Hi folks!
I'm trying to convert a function to work on Linux.
On Windows the code is:

Code:

unsigned long vEax = 0;
unsigned long vEbx = 0;
unsigned long vEcx = 0;
unsigned long vEdx = 0;

__asm
{
        xor eax, eax
        cpuid
        mov vEdx, edx
        mov vEcx, ecx
        mov vEbx, ebx
        mov vEax, eax
}
    


I tried to do the following on Linux:

Code:

unsigned long vEax = 0;
unsigned long vEbx = 0;
unsigned long vEcx = 0;
unsigned long vEdx = 0;

asm( "xorl %eax, %eax" );
asm( "cpuid" );
asm( "movl %edx, vEdx" );
asm( "movl %ecx, vEcx" );
asm( "movl %ebx, vEbx" );
asm( "movl %eax, vEax" );
    


When I compile the code I get the following error:

Code:
CpuID.cppSad.text+0xc)||undefined reference to `vEdx'|
CpuID.cppSad.text+0x12)||undefined reference to `vEcx'|
CpuID.cppSad.text+0x18)||undefined reference to `vEbx'|
CpuID.cppSad.text+0x1d)||undefined reference to `vEax'|
    


I don't know what is wrong, because the variables are declared properly.
What is missing here?

My best regards.
Cthulhu
Post 15 Sep 2008, 20:35
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 15 Sep 2008, 23:03
Accessing external symbols from inline AT&T assembly is very hard (and on other side, much more powerful and complete than simplistic MS way).

Quick googling: http://homepage.fudan.edu.cn/~euler/gcc_asm/inline-3.html
Post 15 Sep 2008, 23:03
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 16 Sep 2008, 00:13
Use external assembly modules instead, then you don't have to worry about compiler-specific features (the big 32bit x86 OSes tend to use the same calling convention, so you can reuse your assembly code).
Post 16 Sep 2008, 00:13
View user's profile Send private message Visit poster's website Reply with quote
Cthulhu



Joined: 12 May 2005
Posts: 29
Cthulhu 16 Sep 2008, 11:05
Thank you guys.
I think I'll try to use external assembly modules then.
Post 16 Sep 2008, 11:05
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 16 Sep 2008, 16:16
It obviously has a bit more overhead than inline assembly since it can't be, well, inlined Smile, but usually this isn't a problem for anything that's actually worth writing in assembly. So IMHO it's definitely the way to go... this also means you can use the full power of FASM Very Happy
Post 16 Sep 2008, 16:16
View user's profile Send private message Visit poster's website Reply with quote
Cthulhu



Joined: 12 May 2005
Posts: 29
Cthulhu 16 Sep 2008, 17:24
I already solved the problem with external assembly modules. Fasm rules!

I also did a "workaround" for the problem, just for test purposes. Just in case anyone else is interested in the solution, I'll post it here:

Code:

    unsigned long vEax = 0;
    unsigned long vEbx = 0;
    unsigned long vEcx = 0;
    unsigned long vEdx = 0;

    asm( "xorl %eax, %eax" );
    asm( "cpuid" );

    asm( "pushl %edx" );
    asm( "popl -16(%ebp)" );

    asm( "pushl %ecx" );
    asm( "popl -12(%ebp)" );

    asm( "pushl %ebx" );
    asm( "popl -8(%ebp)" );

    asm( "pushl %eax" );
    asm( "popl -4(%ebp)" );

    


That way it works.
Post 16 Sep 2008, 17:24
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 16 Sep 2008, 17:30
Cthulhu, that inline assembly is extremely dirty and you can't depend on it working. Check the manuals on GCC's asm statement, it shows how to properly do variable input and output from assembly blocks.
Post 16 Sep 2008, 17:30
View user's profile Send private message Visit poster's website Reply with quote
Cthulhu



Joined: 12 May 2005
Posts: 29
Cthulhu 16 Sep 2008, 18:37
Man you're right.
This way is much better.

Code:
asm ("movl %%edx, %0" : "=m" (vEdx) );
asm ("movl %%ecx, %0" : "=m" (vEcx) );
asm ("movl %%ebx, %0" : "=m" (vEbx) );
asm ("movl %%eax, %0" : "=m" (vEax) );
    


In fact that dirty code caused a segmentation fault in release version.
Post 16 Sep 2008, 18:37
View user's profile Send private message Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 16 Sep 2008, 18:47
A few thing to keep in mind...

first, you should make a single asm block - and you might have to mark it as "volatile", because otherwise GCC is free to do various reordering (dunno if it ever has or ever will, but it's going to bite your butt if it does).

Also, when you have combined into one block, you need to set up the register-clobbering list, so GCC knows what to preserve - this is likely the cause of your segfault.
Post 16 Sep 2008, 18:47
View user's profile Send private message Visit poster's website Reply with quote
Cthulhu



Joined: 12 May 2005
Posts: 29
Cthulhu 16 Sep 2008, 19:10
Thank you f0dder!
I'll take a look at yout tips right now.
Post 16 Sep 2008, 19:10
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
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 vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.