Click here to Skip to main content
15,879,239 members
Please Sign up or sign in to vote.
4.00/5 (1 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
C++
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
Comments
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 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.
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.

you have to use both syntax..


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



and compile without -masm=intel
 
Share this answer
 
Comments
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...
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.
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900