I have got (yet another) problem with x86_64/AT&T/gas/gcc.
I am trying to rewrite a simple function that calculates arc-cosines in
assembly but I can't seem to get the compiler to generate good floating
point numbers (doubles) and I also get a SIGSEGV.
Here is the code in file asmacos.s :
(IT'S AMD64 ASSEMBLY SO ARGUMENTS ARE NOT PUT ON THE STACK!)
2 .section .data
4 .double 1.257e1, 1.888e1
6 .section .text
7 # double asm_acos(double x, int precision)
8 # (xmm0) (xmm0) (edi)
9 # ecx : int i = precision
10 # xmm7 : double delta = (1-x)/precision
11 # xmm6 : double Xn = 1 ; double XnOld = 1 + delta
14 .globl asm_acos
15 .type asm_acos, @function
17 pushq %rbp
18 movl %edi, %ecx
20 # delta = (1-x)/precision :
21 # mov $1.0, %xmm7 :
22 movd Xn_XnOld , %xmm7
23 subsd %xmm0, %xmm7
24 divsd %xmm7, %xmm0
25 gcc asmacos.s acosSSE.c -o acosSSE -g -W -Wall
26 # mov (1.0, 1.0), %xmm6
27 movapd Xn_XnOld, %xmm6
29 addsd %xmm7, %xmm6
31 popq %rbp
This doesn't actually do anything interesting for the time being; I'm
just testing (and unsuccessfully too ^_^).
I added this prototype inside my C file (acosSSE.c):
extern double asm_acos(double x, int precision);
I then call the function like any other C function.
I compile like so:
gcc asmacos.s acosSSE.c -o acosSSE -g -W -Wall
(I don't get any messages)
When I run acosSSE, I get a SIGSEGV (gdb output):
Program received signal SIGSEGV, Segmentation fault.
asm_acos () at asmacos.s:27
27 movapd Xn_XnOld, %xmm6
and I have no idea why.
Worse even, when I do:
(gdb) print /f Xn_XnOld
$26 = 9.12120433e-33
(gdb) print (double)Xn_XnOld
$32 = 171798692
And I've also got just another small question:
As I'm not planning on using the stack at all in this function, can't
I just omit the usual "pushq %rbp" and "popq %rbp"?
||7/17/2009 10:43:11 PM
> When I run acosSSE, I get a SIGSEGV (gdb output):
> Program received signal SIGSEGV, Segmentation fault.
> asm_acos () at asmacos.s:27
> 27 movapd Xn_XnOld, %xmm6
> and I have no idea why.
Again, a WAG. In 32-bit code "movapd" requires memory data to be aligned
on a 16-byte boundary. In Nasmese:
movapd xmm0, [mynum]
movapd [mynum], xmm0
mov eax, 1 ; sys_exit... in 32-bit code...
section .data align=16
dummy db 0
mynum dq 1.23, 4.65
That'll segfault if I don't specify alignment in *both* the section
declaration *and* on the individual variable. (in 64-bit, your sections
may be better-aligned by default???). Or, you could use "movupd", which
doesn't require the alignment.
> Worse even, when I do:
> (gdb) print /f Xn_XnOld
> $26 = 9.12120433e-33
> (gdb) print (double)Xn_XnOld
> $32 = 171798692
Can't help ya there...
> And I've also got just another small question:
> As I'm not planning on using the stack at all in this function, can't
> I just omit the usual "pushq %rbp" and "popq %rbp"?
I would guess so... "bt" might not work, so you might not want to...
> Any ideas?
Sure! (fools rush in where angels fear to tread :) Hope it helps...
7/18/2009 5:20:21 PM
Thanks a lot, adding ".align 16" just after the ".data" solved my
segmentation fault problem but the numbers still deem weird. Anyhow,
I'll continue writing the code and see what happens.
7/18/2009 7:32:57 PM
(page loaded in 0.141 seconds)