Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: ASM g++ inline Intel
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 Frown | :-( . 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 5:30am
Comments
Kenneth Haugland at 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 at 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 at 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 at 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 at 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 at 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 at 3-Aug-12 2:49am
   
Not the right day to quit smoking, I am afraid.
YvesDaoust at 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 at 3-Aug-12 13:47pm
   
Ouch...
 
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...
 
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

you have to use both syntax..
 

ex)
#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
  Permalink  
Comments
YvesDaoust at 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
good
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.
  Permalink  

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

  Print Answers RSS
0 Maciej Los 295
1 OriginalGriff 249
2 Sergey Alexandrovich Kryukov 205
3 Aajmot Sk 197
4 Sinisa Hajnal 176
0 OriginalGriff 7,800
1 Sergey Alexandrovich Kryukov 7,072
2 DamithSL 5,604
3 Manas Bhardwaj 4,986
4 Maciej Los 4,790


Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 4 Sep 2012
Copyright © CodeProject, 1999-2014
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