LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 07-02-2010, 10:45 PM   #1
xuancong
LQ Newbie
 
Registered: Jul 2010
Posts: 18

Rep: Reputation: 0
Thumbs down Stupid GCC inline assembler doesn't even support local variable


Hi,

It's good that GCC support inline assembly Intel syntax, but it cannot even simply address local variables/parameters properly, making itself stupid and essentially useless, look at the following example:

Code:
// In MSVC, this compiles successfully
int main(int argc, char *argv[])
{
        int x=1, f=2, fa=3;
        __asm{
                    int 3
                    mov eax, [x+4]
                    movss xmm1,[f+4]
                    fld [fa+4]
        }
        return 0;
}
Code:
// In GCC AT&T syntax, this compiles successfully
int main(int argc, char *argv[])
{
        int x=1, f=2, fa=3;
        asm("int $0x3");
        asm("mov 4%0,%%eax"::"m"(x));
        asm("movss 4%0,%%xmm1"::"m"(f));
        asm("fld 4%0"::"m"(fa));
        return 0;
}
Code:
// In GCC Intel syntax, this would fail to compile
int main(int argc, char *argv[])
{
        int x=1, f=2, fa=3;
        asm(".intel_syntax noprefix\n"
               "int 3\n"
               "mov eax, [x+4]\n"
               "movss xmm1,[f+4]\n"
               "fld [fa+4]\n"
               ".att_syntax\n");
        return 0;
}
The third piece of code would fail to compile under GCC, because although it supports intel syntax it cannot handle local variables nor function parameters. I hope future versions of GCC can support this feature better. Thanks!

Best regards,
Wang Xuancong

Last edited by xuancong; 07-05-2010 at 02:47 AM. Reason: half problem solved
 
Old 07-02-2010, 10:56 PM   #2
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Personally, I think Intel's bass-ackwards syntax is "stupid".

I vastly prefer the consistency of ATT syntax. And I especially like being able to use the same general syntax across many different architectures (the Sun does NOT rise and set on Intel 80x86!).

Worse, there's a ton of Intel MASM based assembly code available on the web - most of it written for 16-bit *DOS*. Which, of course, tends to instill some very bad habits for anybody who wants to learn assembly on a modern, VMM-based OS.

I'd strongly encourage anybody interested in assembly to learn both ATT and Intel syntax. I'd even go so far as suggesting they learn ATT *first* (then decide which they prefer after becoming conversant in BOTH).

IMHO .. PSM
 
4 members found this post helpful.
Old 07-03-2010, 12:52 AM   #3
xuancong
LQ Newbie
 
Registered: Jul 2010
Posts: 18

Original Poster
Rep: Reputation: 0
Hey Guys,
If you don't know how to solve this problem, don't post non-sense, ok? Apparently, AT&T syntax cannot achieve the same functionality as the Intel syntax in my case.
XC
 
0 members found this post helpful.
Old 07-03-2010, 01:37 AM   #4
ForzaItalia2006
Member
 
Registered: Dec 2009
Location: Walldorf, Germany
Distribution: (X)Ubuntu, Arch, Gentoo
Posts: 205

Rep: Reputation: 67
Quote:
Originally Posted by xuancong View Post
Hey Guys,
If you don't know how to solve this problem, don't post non-sense, ok? Apparently, AT&T syntax cannot achieve the same functionality as the Intel syntax in my case.
XC
I didn't read your complete post, because you seem to be missing important tags to make your post readable. Furthermore, I don't have much experience with inline assembler, but just for the case you don't get any qualified answer in this forum, you could post your questions (possibly a bit shorten and more compact) to the GCC mailing list ...

Andi

P.s. I don't think that paulsm4's post is senseless!!!
 
2 members found this post helpful.
Old 07-03-2010, 02:15 AM   #5
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
The following quote as taken from GCC inline assembler but I'm fairly stupid and don't know assembler which is why I used a search engine.
Quote:
int main(void)
{
int foo = 10, bar = 15;
__asm__ __volatile__("addl %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
printf("foo+bar=%d\n", foo);
return 0;
}

Here we instruct gcc to store foo in eax (constraint a) and bar in ebx (constraint b). We further declare that foo is only written (constraint modifier =). No registers are clobbered besides the declared output registers.
 
1 members found this post helpful.
Old 07-03-2010, 06:26 AM   #6
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,083

Rep: Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110
Quote:
Originally Posted by xuancong View Post
If you don't know how to solve this problem, don't post non-sense
I totally agree with you regarding paulsm4's post, but:

Quote:
Apparently, AT&T syntax cannot achieve the same functionality as the Intel syntax in my case.
That is also nonsense. AT&T syntax supports everything you're trying to do. Your lack of knowledge regarding both AT&T syntax and gcc inline assembler doesn't make either of those things stupid nor inadequate. It might make them the wrong tools for you.

You seem to want to write almost all of a function in assembler. GCC inline assembler is quite difficult to master. Writing a whole function in assembler (and assembling it separately with NASM) is far easier than writing most of a function in assembler.

You could change to a whole function in assembler. I know that could work and I think it would be easiest.

You could switch to AT&T syntax. I know that could work. I know AT&T syntax has full support for everything you're trying to do. But that doesn't make the translation easy.

You could stick to roughly the code you have now but modify it to correctly mix C and asm code according to gcc rules. I think that could work. I don't know Intel syntax gcc inline syntax well enough to be certain.

Quote:
Originally Posted by xuancong View Post
it cannot even simply address local variables/parameters properly, making itself stupid and essentially useless
Certainly gcc inline asm can address local variables. It is a very powerful tool that can do far more than MS inline asm can do. But it doesn't have an "easy" mode.

The syntax for the asm instructions themselves is ordinary, but there is a whole extra language you need to know to make the connection between a chunk of asm code and the world outside that chunk of asm code (especially local variables in the same function).

That extra language is difficult and generally not worth it. It is usually better to write a whole function in ordinary asm rather than part of a function in inline asm.

Last edited by johnsfine; 07-03-2010 at 06:41 AM.
 
2 members found this post helpful.
Old 07-03-2010, 06:43 AM   #7
pr_deltoid
Member
 
Registered: Jun 2010
Distribution: Fedora
Posts: 289

Rep: Reputation: 41
Quote:
Originally Posted by xuancong View Post
Hey Guys,
If you don't know how to solve this problem, don't post non-sense, ok? Apparently, AT&T syntax cannot achieve the same functionality as the Intel syntax in my case.
XC
Hey xuancong,
try posting your code in "[ code ]" "[ /code ]" so it comes up nice and neat instead of smashed together. It looks like non-sense. If you don't want to have any manners or go through the effort of trying to post readable code, don't expect instant help. Expect to linger around here for a while and check on your thread over and over again or complain at everyone.

Last edited by pr_deltoid; 07-03-2010 at 06:49 AM.
 
Old 07-03-2010, 06:58 AM   #8
pr_deltoid
Member
 
Registered: Jun 2010
Distribution: Fedora
Posts: 289

Rep: Reputation: 41
http://www.reversing.be/article.php?...51203194931893
Quote:
Level : newbie
Quote:
#include <stdio>
#include <string.h>
char inlined[] = "this is a message from intel syntaxed inlined assembly code\n";
int len;
int main (void)
{
printf("this is a sample intel syntaxed and inlined c program\n");
len = strlen(inlined);
printf("%d\n",len);
asm(".intel_syntax noprefix\n");
asm("mov edx,len\n");
asm("mov ecx,offset inlined\n");
asm("mov ebx,1\n");
asm("mov eax,4\n");
asm("int 0x80\n");
printf("probably it is a success look in gdb\n");
return 1;

notice the first line :

asm(".intel_syntax noprefix\n");

This denotes that the folowing assembly snippet uses intel syntax to the
native assembler gas
Apparently it supports inline Intel syntax assembly, so what are you talking about? What are you having a problem with, specifically? Try posting your code in [ code ] [ /code ] (no spaces) like I said. It makes it much neater and no one has to go through any trouble to read it easily. Point out what, specifically, you're having trouble with. Anything.
If you want people to read your code and figure it out for you, make your code neat and easy to read.

Last edited by pr_deltoid; 07-03-2010 at 07:10 AM.
 
1 members found this post helpful.
Old 07-03-2010, 07:54 AM   #9
johnsfine
Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,083

Rep: Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110Reputation: 1110
Quote:
Originally Posted by prdeltoid View Post
so what are you talking about? What are you having a problem with, specifically?
The main issue is that the OP wants to be able to declare a local variable in C code, such as
Code:
float vout[4];
then read and write the elements of that variable in the inline asm code.

I think I already gave the best answer to that question, which is: Don't do that, instead write the whole function in asm.

Another good answer would be a link to the tutorial (I've misplaced that link myself) that does a good job of explaining the obscure syntax gcc has for connecting local variables into inline asm.

I expect the OP would prefer if someone provided the exact syntax, fitting this example, for both declaring the use of vout[4] by the inline asm and actually reading and writing the elements within the asm code. I don't have the expertise to do that from memory, nor the patience to look up and then test the details, nor the belief that it is the best thing to give the OP.

I obviously think there is a fundamental difference between my non answer ("instead write the whole function in asm") and the other non answers posted here (such as Paulsm4's "learn ATT *first*"). Hopefully xuancong can see that difference, rather than just seeing non answers. (I also just thanked Pualsm4 for valuable help in an unrelated thread. I hope I won't be losing such help by my comments here.)

Last edited by johnsfine; 07-03-2010 at 08:04 AM.
 
Old 07-03-2010, 07:58 AM   #10
pr_deltoid
Member
 
Registered: Jun 2010
Distribution: Fedora
Posts: 289

Rep: Reputation: 41
http://www.drpaulcarter.com/pcasm/
http://www.ibm.com/developerworks/library/l-ia.html
http://www.ibiblio.org/gferg/ldp/GCC...bly-HOWTO.html

Last edited by pr_deltoid; 07-03-2010 at 11:02 AM.
 
Old 07-03-2010, 02:51 PM   #11
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hey, xuancong -

You don't walk in to somebody else's home as a guest and immediately start calling things "stupid". That's simply rude

It's also "stupid"

Q: Is there any specific thing you tried, but were unable to do with ATT syntax?

Thanx in advance .. PSM

PS:
You cut/pasted EXACTLY the same ("stupid") rant on other sites, and you cut/pasted the same ("ignorant", "nasty" - you choose ) response when people there legitimately tried to help you. For example:

Quote:
http://www.programmingforums.org/thread28122.html

Reading the rules and guidelines and adhering to them is not nonsense. Failing to do so will get you ignored or worse. I programmed asm exclusively for years but I now have zero interest in your problem. I WOULD be surprised if the choice of a set of mnemonics for the machine code was a show-stopper.
And again - GCC should *fully* support *anything* you want to do. Honest.

Last edited by paulsm4; 07-04-2010 at 02:45 PM.
 
1 members found this post helpful.
Old 07-04-2010, 09:06 PM   #12
xuancong
LQ Newbie
 
Registered: Jul 2010
Posts: 18

Original Poster
Rep: Reputation: 0
Unhappy sorry, but the problem indeed has no solution

Hey guys,
I might have been rude since I searched throughout Google and manuals and tried all possible ways but still cannot find the solution. I'm getting so frustrated and started by calling things 'Stupid'. I apologize for that.

However, I don't blame things for no reasons, in fact if any one of you can translate the following 3 instructions into GCC inline assembly syntax, either AT&T or Intel, the entire problem is solved:
Code:
// MSVC inline syntax --> GCC intel or AT&T inline syntax
mov eax, [x]  -->    ""::"a"(x)
mov eax, [x+4]   --> ?
movss xmm1,[f+4]   --> ?
fld dword ptr [fa+4] --> ?
where x,f and fa are local variables or function parameters. I've already figured out how to translate the 1st instruction exactly as it is. Take note that you are not allowed to make use of any other registers since all of them are in use; and you are not allowed to pushing any registers onto stack and use them temporarily since that will slow down speed.

Thanks!
XC

Last edited by xuancong; 07-04-2010 at 09:09 PM.
 
Old 07-05-2010, 01:08 AM   #13
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi, xuancong -

1. Thank you for your apology, and thank you for your clarification.

2. I'm still not sure exactly what you're looking for, and please allow me to apologize in advance if I haven't understood you correctly

3. I believe these two snippets are absolutely equivalent:
Code:
// Intel syntax: this compiles successfully
int myfunc(float f){
 int x;
 float fa[8];
 asm(".intel_syntax noprefix\n"
  "mov eax, [x]\n"  // compile fail 1
  "movss xmm1,[f]\n"  // compile fail 2
  "fld dword ptr [fa+4]\n" // compile fail 3
  ".att_syntax\n"
 );
}
Code:
// ATT syntax: this also compiles successfully
int myfunc(float f){
 int x;
 float fa[8];
  asm (
    "mov x,%eax\n"
    "movss f,%xmm1\n"
    "flds (fa+4)\n"
  );
}
Look at the syntax for the "mov" instruction (Intel syntax) here:
Quote:
http://en.wikipedia.org/wiki/MOV_%28x86_instruction%29

1. Move the contents of the register bx into the register ax
Code:
MOV ax, bx
2. Move the contents of the register ax into the referenced memory block
Code:
MOV [address], ax
3. A combination which is not possible, is a move from memory to memory. For example :
Code:
MOV [address1], [address2]
4. To achieve this, MOV must be used in sequence:
Code:
MOV ax, [address2]
MOV [address1], ax
You'll notice that the square brackets are NOT used in ATT syntax.
This link might also be useful:
http://maven.smith.edu/~thiebaut/Art...tml#HEADING2-1

'Hope that helps ... and again, apologies if I've misunderstood what you're trying to accomplish.

Your .. PSM

PS:
My favorite book on Linux Assembly is:
"Professional Assembly Language", Richard Blum

The only down side is that he hasn't written an update that covers 64-bit ASM yet...

Last edited by paulsm4; 07-05-2010 at 01:24 AM.
 
Old 07-05-2010, 01:30 AM   #14
xuancong
LQ Newbie
 
Registered: Jul 2010
Posts: 18

Original Poster
Rep: Reputation: 0
Exclamation

Quote:
Originally Posted by paulsm4 View Post
Code:
// ATT syntax: this also compiles successfully
int myfunc(float f){
 int x;
 float fa[8];
  asm (
    "mov x,%eax\n"
    "movss f,%xmm1\n"
    "flds (fa+4)\n"
  );
}
Oh, GOD! In GCC 4.4.3, this doesn't compile although your syntax is theoretically meaningful.
 
Old 07-05-2010, 09:34 AM   #15
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,455

Rep: Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843
Quote:
Originally Posted by paulsm4
// ATT syntax: this also compiles successfully
It compiles but it doesn't link, and if you turn on warnings you'll notice that it doesn't actually use the variables you named in the code, it assumes they are global symbols to be resolved at link time.

This links, can't really test it because it's just fragments:
Code:
int myfunc_att(float f){
    int x;
    float fa[8];
    asm (
         "mov %0, %%eax\n"
         "movss %1, %%xmm1\n"
         "flds (%2)\n"
         :                           /* outputs */
         : "g"(x), "g"(f), "g"(fa+4) /* inputs */
         : "%eax", "%xmm1"           /* clobber */
         );
}

int main() { return 0; }
As far as I can tell, this can't work with Intel syntax because when variables are subbed for their asm value, gcc always puts ATT syntax.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to give inline comment at variable declaration in Makefile w/o including space..? mayankmehta83 Linux - Newbie 6 12-07-2009 04:33 AM
Gcc Assembler And Link eichmen Programming 4 04-17-2007 07:14 AM
Problem with variable in inline assembler DavidW567 Programming 0 05-17-2005 11:21 AM
Compiling inline assembler DavidW567 Programming 3 03-07-2005 08:59 AM
inline assembly in gcc gursev Programming 2 03-04-2005 02:17 AM


All times are GMT -5. The time now is 11:36 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration