Why won't the simple built-in build function work in GCC?

I have a simple built-in build function that works fine in MSVC , but for some reason refuses to work under Apple GCC 4.2.1 (i386 arch, forced 32-bit mode). Fortunately, the much more complex build functions work fine, however, I cannot understand why this will not work ... Unfortunately, I cannot debug it - when I look at things, there is no register window in Xcode 4.0.2 (this was in versions 3.2 ).

I am sure the problem is not with Intel style build .

int Convert(double value) { _asm { fld value push eax fistp dword ptr [esp] pop eax } // The returned value is insane } 
+4
source share
4 answers

Fortunately, much more complex build functions work fine [...]

Are they also built-in build functions? Because GCC uses a completely different syntax for inline assembler. You can make the syntax more familiar, but see wikipedia .

 1 int Convert(double value) 2 { 3 int result; 4 __asm__ __volatile__ ( 5 "fist %0\n\t" 6 : "=m" (result) 7 : "t" (value) 8 ); 9 return result; 10 } 

How do i do that. =m indicates that we want the memory operand to save the result (we do not want the register as fist not to work with them). t indicates that the value is being passed at the top of the stack, which also provides the correct cleanup for us.

EDIT:

Another thing to try, assuming gcc with xcode allows the same inline assembler as msvc:

  int Convert(double value) { int result; _asm { fld value push eax fistp dword ptr [esp] pop eax mov [result], eax } return result; } 

It should also overshadow the warnings about missing return values ​​that you are likely to receive. It just might be that it is more strict to allow you to return values ​​from assembler blocks, write eax than msvc.

+8
source

Your code works fine for me with Apple gcc 4.2.1:

 #include <stdio.h> static int Convert(double value) { _asm { fld value push eax fistp dword ptr [esp] pop eax } } int main(void) { int i = Convert(42.0); printf("i = %d\n", i); return 0; } 


 $ gcc -v Using built-in specs. Target: i686-apple-darwin10 Configured with: /var/tmp/gcc/gcc-5666.3~123/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 Thread model: posix gcc version 4.2.1 (Apple Inc. build 5666) (dot 3) $ gcc -Wall -m32 -O3 -fasm-blocks convert.c -o convert convert.c: In function 'Convert': convert.c:14: warning: no return statement in function returning non-void $ ./convert i = 42 

I assume that you are inadvertently compiling for 64 bits. Take a look at the build script in Xcode and make sure you can see -m32 when compiling this code - it’s easy to configure the parameter to get something in the project. You can also try creating and running my sample code from the command line to make sure that it works with your toolchain.

+2
source

The GCC syntax requires that you specify which variables you intend to use inside the encoded part of the assembly. The laid out code does not do this and can actually work in random memory instead of the variables you expect.

In addition, GCC has some ability to use call conventions other than the "transfer everything on the stack" standard (for example, fastcall and tail recursive calls). The assembly code provided assumes that everything is passed on the stack. You may have a mismatch between the expected build code and what GCC does.

The build code in user786653 responds by avoiding these issues.

+1
source

It worked fine for me in Xcode 4.0.2 (with control warnings reaching the end of a non-void function). I created the project in 3.2.6, and when I first downloaded it in Xcode 4.0.2, it will not compile. I finally got it for compilation after I installed the architecture in 32-bit, Valid Architecture for i386 and the compiler in GCC 4.2. When the compiler is installed in LLVM GCC 4.2, it starts, but the function returns 0.

Compiler set to LLVM GCC 4.2Compiler set to GCC 4.2

0
source

All Articles