Reputation: 1501
I have a simple inline assembly function, which works fine in MSVC, but for some reason refuses to work under Apple GCC 4.2.1 (i386 arch, forced 32-bit mode). Fortunately, much more complex assembly functions work fine, however I can't fathom why won't this one work... Unfortunately, I can't debug it - by the look of things there is no registers window in XCode 4.0.2 (it was in 3.2 versions).
I'm positive that the problem is not related with Intel style assembly.
int Convert(double value)
{
_asm
{
fld value
push eax
fistp dword ptr [esp]
pop eax
}
// The returned value is insane
}
Upvotes: 4
Views: 4185
Reputation: 10698
It worked fine for me in Xcode 4.0.2 (with warnings about control reaching end of non-void function). I created the project in 3.2.6 and when I first loaded it into Xcode 4.0.2 it wouldn't compile. I finally got it to compile after I set the Architecture to 32-bit, the Valid Architecture to i386, and the compiler to GCC 4.2. With the compiler set to LLVM GCC 4.2, it runs but the function returns 0.
Upvotes: 0
Reputation: 20021
GCC's syntax requires you to specify which variables you're going to use inside the assembly coded portion. The posted code doesn't do that, and may in fact be operating on random memory instead of the variables you expect to.
Additionally, GCC has some ability to use calling conventions other than the standard "pass everything on the stack" (eg., fastcall and tail recursive calls). The assembly code posted assumes that everything is passed on the stack. You may have a mismatch between what your assembly code expects and what GCC is doing.
The assembly code in user786653's answer avoids these problems.
Upvotes: 1
Reputation: 30450
Fortunately, much more complex assembly functions work fine[...]
Are these also inline assembly functions? Because GCC uses a completely different syntax for inline assembler. You can make the syntax look more familiar though, 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 }
Is how I would do it. =m
specifies that we want a memory operand to store the result in (we don't want a register as fist
doesn't work with those). t
specifies that the value is passed on the stack top, that also ensures proper cleanup for us.
EDIT:
Another thing to try, assuming gcc with xcode allows the same kind of inline assembler as msvc, is:
int Convert(double value)
{
int result;
_asm
{
fld value
push eax
fistp dword ptr [esp]
pop eax
mov [result], eax
}
return result;
}
That should also shut up the warnings about missing return values you're probably getting. It might simply be that it is more strict about allowing you to return values from assembler blocks by writing eax than msvc.
Upvotes: 8
Reputation: 212929
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
My guess is that you are inadvertently compiling for 64 bit. Take a look at the build transcript in Xcode and make sure you can see -m32
when compiling this code - it's easy for a setting to get overriden somewhere in the project. You can also try building and running my code example above from the command line to make sure it works with your toolchain.
Upvotes: 2