Page 1 of 2

Stupid GCC inline assembly CANNOT even handle local variable

Posted: Fri Jul 02, 2010 9:20 pm
by xuancong
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: Select all

// 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: Select all

// 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: Select all

// 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

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Fri Jul 02, 2010 10:56 pm
by pcmattman
  1. Code tags. Use them.
  2. Learn how to write inline assembly.

Code: Select all

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"
);
}
Once you learn how to write inline assembly... properly, you'll know how to do that.

If you really want Intel syntax over AT&T (some people prefer intel syntax, for whatever reason) - write the assembly yourself in a specific file and assemble with NASM or something, then link into your kernel. Works much better than forcing GAS/GCC to try and read intel syntax.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sat Jul 03, 2010 4:30 am
by Creature
In short: Intel syntax in GCC is way different from e.g. Intel syntax in Visual C++. You STILL have to use the output and input parameters in Intel syntax (but I believe you can use an Assembly 'alias' for variables that will work on the fly (so you can bypass the input/output lists), there's something on the wiki and the GCC docs about that). I also understand your frustration, I like the Visual C++ inline assembly more myself (although it has its disadvantages as well), but I guess this is just the way we have to do it!

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sat Jul 03, 2010 4:53 am
by xuancong
Thanks! I've searched throughout Google, but there is no solution. Don't think about anything else, just solve the 3 compile failure instructions will suffice. My objective is that when all general purpose registers are in use, I have to use direct offset-memory-operand instructions like "fld dword ptr [ebp+30]" which does not use any register. Well, GCC support this but I dont know where my local variables are on the stack. Unfortunately, the relative positions of local variables w.r.t frame pointer EBP is compiler and compiler-option dependent, I should never hardcode or will easily mess up.

From another point of view, it also means that the AT&T GCC extended syntax is somewhat inferior to Intel syntax, because there are certain particular sequences of particular instructions which AT&T just cannot handle.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sat Jul 03, 2010 5:10 am
by fronty
xuancong wrote:From another point of view, it also means that the AT&T GCC extended syntax is somewhat inferior to Intel syntax, because there are certain particular sequences of particular instructions which AT&T just cannot handle.
Could you point these instructions? I've never seen any instructions that GNU's assembler can't handle with AT&T syntax, though I haven't written much assembly for PC, so I'd like here about this.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sat Jul 03, 2010 6:00 am
by Owen
xuancong wrote:Thanks! I've searched throughout Google, but there is no solution. Don't think about anything else, just solve the 3 compile failure instructions will suffice. My objective is that when all general purpose registers are in use, I have to use direct offset-memory-operand instructions like "fld dword ptr [ebp+30]" which does not use any register. Well, GCC support this but I dont know where my local variables are on the stack. Unfortunately, the relative positions of local variables w.r.t frame pointer EBP is compiler and compiler-option dependent, I should never hardcode or will easily mess up.

From another point of view, it also means that the AT&T GCC extended syntax is somewhat inferior to Intel syntax, because there are certain particular sequences of particular instructions which AT&T just cannot handle.
There is no sequence of instructions that GCC inline assembly cannot handle. Really.

You just need to RTFM. Yes, GCC inline assembly is more complex than MSVC's. Guess what? It generates significantly faster code, because it doesn't cripple the optimizer and allows the register allocator to do its job properly.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sun Jul 04, 2010 4:19 am
by skyking
xuancong wrote:Thanks! I've searched throughout Google, but there is no solution. Don't think about anything else, just solve the 3 compile failure instructions will suffice. My objective is that when all general purpose registers are in use, I have to use direct offset-memory-operand instructions like "fld dword ptr [ebp+30]" which does not use any register. Well, GCC support this but I dont know where my local variables are on the stack. Unfortunately, the relative positions of local variables w.r.t frame pointer EBP is compiler and compiler-option dependent, I should never hardcode or will easily mess up.
You simply hasn't searced enough. Since this is an extension to the standard you should of course read the compiler manual:

http://gcc.gnu.org/onlinedocs/
From another point of view, it also means that the AT&T GCC extended syntax is somewhat inferior to Intel syntax, because there are certain particular sequences of particular instructions which AT&T just cannot handle.
Or maybe your research has not been through enough to find out how "certain particular sequences of particular instruction" should be written in AT&T syntax?

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sun Jul 04, 2010 10:00 am
by Solar
Write the command you want in whatever ASM dialect you like, and assemble to object code. Feed it to objdump -D, and there you have your AT&T equivalent. It's as easy as that.

I don't blame things for no reasons

Posted: Sun Jul 04, 2010 8:14 pm
by xuancong
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: Select all

// 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

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sun Jul 04, 2010 8:36 pm
by xuancong
Solar wrote:Write the command you want in whatever ASM dialect you like, and assemble to object code. Feed it to objdump -D, and there you have your AT&T equivalent. It's as easy as that.
I know so, but that will complicate the compilation process and not all platforms support the same assembler, but they all support GCC. It'll be better if GCC inline assembler can handle this directly.

XC

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sun Jul 04, 2010 10:14 pm
by Solar
#-o

It's not about GCC being able to handle anything, it's about you learning.

You could've called this thread "Stupid me CANNOT even figure out AT&T addressing", because that's what it's all about.

And you guess what? Even without asking this question, you got it answered in this thread, multiple times. Now it's your turn actually getting down from your blaming GCC, and starting to study.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sun Jul 04, 2010 11:19 pm
by xuancong
Solar wrote:#-o

It's not about GCC being able to handle anything, it's about you learning.

You could've called this thread "Stupid me CANNOT even figure out AT&T addressing", because that's what it's all about.

And you guess what? Even without asking this question, you got it answered in this thread, multiple times. Now it's your turn actually getting down from your blaming GCC, and starting to study.
So you still cannot solve the problem, right? I've already reduced the problem to only 3 instructions. Take a look at my reply! Again, I've already read through AT&T manual and have already figured out that GCC inline asm AT&T addressing cannot handle these 3 instructions. NOT I cannot figure out AT&T. In fact, AT&T can, GCC inline cannot.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Sun Jul 04, 2010 11:58 pm
by pcmattman
Right, because it's clear you're an idiot and would rather blame your tools than do something for yourself...
Write the command you want in whatever ASM dialect you like, and assemble to object code. Feed it to objdump -D, and there you have your AT&T equivalent. It's as easy as that.
I did this for you, because you're too pig-headed to listen to a good idea:

Code: Select all

Disassembly of section .text:

00000000 <x-0x18>:
   0:   a1 18 00 00 00          mov    0x18,%eax
   5:   a1 1c 00 00 00          mov    0x1c,%eax
   a:   f3 0f 10 0d 24 00 00    movss  0x24,%xmm1
  11:   00 
  12:   d9 05 2c 00 00 00       flds   0x2c
Look at that! AT&T syntax! The constants here are in fact references to symbols... if you know how to dereference a variable in AT&T assembly, you'll know how to get this code into inline assembly:

Code: Select all

	asm volatile(
		"movss (%0), %%xmm1\n"
		"fld %1" : : "a" (x), "f" (f), "m" (fa[0]));
"mov eax, [x+4]" in AT&T assembly is:

Code: Select all

mov (x + 4), %eax
I'm sure you can figure out the rest. Stop wasting everyone's time.

EDIT: This page (found in mere seconds of Googling might help you figure out the translations as well.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Mon Jul 05, 2010 12:18 am
by xuancong
pcmattman wrote:Right, because it's clear you're an idiot and would rather blame your tools than do something for yourself...
Write the command you want in whatever ASM dialect you like, and assemble to object code. Feed it to objdump -D, and there you have your AT&T equivalent. It's as easy as that.
I did this for you, because you're too pig-headed to listen to a good idea:

Code: Select all

Disassembly of section .text:

00000000 <x-0x18>:
   0:   a1 18 00 00 00          mov    0x18,%eax
   5:   a1 1c 00 00 00          mov    0x1c,%eax
   a:   f3 0f 10 0d 24 00 00    movss  0x24,%xmm1
  11:   00 
  12:   d9 05 2c 00 00 00       flds   0x2c
Look at that! AT&T syntax! The constants here are in fact references to symbols... if you know how to dereference a variable in AT&T assembly, you'll know how to get this code into inline assembly:

Code: Select all

	asm volatile(
		"movss (%0), %%xmm1\n"
		"fld %1" : : "a" (x), "f" (f), "m" (fa[0]));
"mov eax, [x+4]" in AT&T assembly is:

Code: Select all

mov (x + 4), %eax
I'm sure you can figure out the rest. Stop wasting everyone's time.

EDIT: This page (found in mere seconds of Googling might help you figure out the translations as well.
Take note that your code doesn't do what my code (the 3 lines) does at all: the memory offsets are all gone. I want "movss xmm1,[x+4]", not "movss xmm1,[x]"; I want "fld [f+4]", not "fld [f]". And you also use EAX to transfer x into xmm1: {:"a"(x)} will change EAX. Don't think I'm so ignorant of AT&T syntax, OK?

And also "mov (x+4),%eax" is not supported by GCC (I use 4.4.3), you get a compile error.

Re: Stupid GCC inline assembly CANNOT even handle local vari

Posted: Mon Jul 05, 2010 12:22 am
by pcmattman
Your code doesn't do what my code (the 3 lines) does at all: the memory offsets are all gone. I want "movss xmm1,[x+4]", not "movss xmm1,[x]"; I want "fld [f+4]", not "fld [f]".
I liked the part where you thought I'd actually spoon feed you, made me laugh a little.
And also "mov (x+4),%eax" is not supported by GCC, you get a compile error.
Yes, that's pure AT&T syntax, not inline assembly.

I've given you a start, now you can figure out the rest.

Also...
Don't think I'm so ignorant of AT&T syntax, OK?
Uh, sure. This thread proves you are in fact ignorant of the syntax, OK?