Click here to Skip to main content
13,139,132 members (72,548 online)
Rate this:
Please Sign up or sign in to vote.
See more:
I am porting existing code from Windows to Linux (Visual C++ to g++). It includes inline assembly sections.

g++ supports a compilation switch (-masm=intel) telling it to accept the Intel syntax instead of the AT&T one. So far so good, it should avoid painful rewriting of thousands of lines.

Anyway, there are issues with referencing the C++ variables outside the inline assembly blocks.

For instance, building
void Test()
  int i;
  asm("mov [i], 5");

results in the linker error undefined reference to `i'. And the assembler seems to get confused with the branching labels.

From Web searches, it seems that local variables cannot be referenced from assembly when using the Intel syntax :-(. I found several related posts, but none rescued me.

This is annoying as I can't make my variables global. (This would break multi-thread safeness and it does not seem to be compatible with namespaces).

Any hint ?
Posted 2-Aug-12 4:30am
Kenneth Haugland 2-Aug-12 10:33am
ITs been a while since I did C or C++, but cant you resolve the situation by using functions?
YvesDaoust 2-Aug-12 10:54am
What do you mean ? I am using functions.

My question is very specific to the behavior of gcc/g++ in the Intel inline assembly compatibility mode.
TRK3 2-Aug-12 13:58pm
Is the inline assembly actually justified?

In this day and age I am having a hard time coming up with a scenario where inline assembly makes sense.

Particularly in a program you are porting from Windows.

With optimizing compilers, it's a rare case where you can hand craft assembly that's significantly faster than C.

So the only reason you are left with for writing assembly would be to do something hardware/OS specific which is not going to be portable from Windows to Linux anyway.

Why not just re-write it in C?

Or if there is a valid reason for the inline assembly, why can't you just convert to AT&T syntax?

How hard could it be to convert from one assembly syntax to another? If you are using the same instruction set, there is a one-to-one mapping. If you aren't using the same instruction set, it isn't portable anyway.

If there is more than a dozen lines of assembler something is wrong anyway.

As for Kenneth's suggestion of using functions -- the idea is that if you pass the variables as parameters to a pure assembly function, then you know where those variables are on the stack relative to the stack pointer (look up C calling convention).
YvesDaoust 2-Aug-12 15:26pm
Thank you for trying to help.

This inline assembly is MMX/SSE code hand crafted for maximum performance. I don't believe that any vectorizing compiler could beat it.

There are more than 10,000 lines of assembly code so rewriting to AT&T syntax is not practical (not talking of the disgust it inspires me.) There is a customer waiting at the door, and the work is 99% done, except for this regrettable restriction.

I am dreaming of a better option than locating the variables on the stack for hundredths of functions.
TRK3 2-Aug-12 15:37pm
Hmm... Clearly I suffered a failure of imagination.

10,000 lines of inline assembly! What was the author smoking?

There are automated tools for converting from one syntax to the other.

If you google "convert intel assembly to at&t" you'll get some links to projects/tools that will do that.

Of course, I suspect they want to take assembly source rather than C with inline assembly instructions, but you might be able to leaverage one of them to do the trick...
YvesDaoust 3-Aug-12 2:49am
Not the right day to quit smoking, I am afraid.
YvesDaoust 3-Aug-12 4:31am
From this quite interesting CodeProject article "Inline Assembly in GCC Vs VC", I understand that my problem is not specific to the Intel syntax: gcc inline assembly just does not support references to local variables. These have to be found in the stack frame :-( (hoping that they have not been optimized away...)
TRK3 3-Aug-12 13:47pm

Can you separate the inline assembly portions into a one (or a small handful) of source files -- preferrably with simple C functions as the interfaces (and no windows dependencies)?

Then you might be able to compile the source into assembly code using the VS compiler on your Windows machine and then use the pure assembly code as source for your Linux project (converting to AT&T using an automated converter if need be).

Alternately you might just look into Wine and see if you can't just use the windows executable or DLL's as-is.

None of it is very attractive (or simple).

Normally I don't advocate a quick and dirty solution, but in this case, if there is a quick solution I am not sure I'd care how dirty it is...

YvesDaoust 6-Aug-12 15:53pm
In the end your suggestion is the right one. One option would be to retrieve the local variables from the stack frame, but it appears very difficult to locate them in optimized code. Passing them as argument should make things easier.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

you have to use both syntax..

#define TEST(out, in) \
            (               \
              "mov %1, 5\n\t"\
              ".intel_syntax noprefix;" \
              --------intel syntax --------
              ".att_syntax;" \
              :"=g" (out) \
              :"g" (in)\

and compile without -masm=intel
YvesDaoust 5-Sep-12 4:18am
Interesting, thank you for contributing. Where did you find this info ?

This is perfectly horrible, I will stick to my Solution 1 !

By the way I am nearly done rewriting all my stuff using intrinsics. In the beginning I was strongly against them, considering that they were just a painful rewrite with no added value. After a while I realized that they nicely take care of register allocation and make your code look human again. I saw no loss of performance compared to my carefully handcrafted assembly; sometimes improvements by 20% or so...
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

In front of the technical difficulties, I am giving up the idea to use inline assembly.

As in any case a full rework of the source code is required, this opens new options.

The option I have chosen is to switch to the SSE intrinsics calls, as they are portable between Microsoft and GNU compilers and appear to be the future of vectorization. Programming with those intrinsics is much easier as you needn't worry about register allocation. In addition, the Visual C++ compilers do not support inline assembly for 64 bits processors, compelling the use of the intrinsics.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web04 | 2.8.170915.1 | Last Updated 4 Sep 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100