0

I am experimenting on modifying assembly program by calling c library (add.c) from assembly, I ran into segmentation fault in movsd %xmm0, (%rax). Any idea to resolve this issue, I am new to assembly.

I have created library add.c which performs multiplication. The call should be invoked from assembly.

My exp1.c looks like

exp1.c is

double *a,*b,*c;
int main()
{
double a_d = 1.1;
double b_d = 2.1;
double c_d;
c = &c_d;
a = &a_d;
b = &b_d;
*c = (*a + *b);
printf("\n%lf",*c);
}

add.c is 

#include<stdio.h>
double add(double a_me, double b_me){
double c = a_me*b_me;
printf("\n%lf and %lf is %lf\n",a_me,b_me,c);
return c;   }

.file   "add.c"
        .text
        .globl  add
        .type   add, @function
add:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movsd   %xmm0, -24(%rbp)
        movsd   %xmm1, -32(%rbp)
        movsd   -24(%rbp), %xmm0
        mulsd   -32(%rbp), %xmm0
        movsd   %xmm0, -8(%rbp)
        movq    -8(%rbp), %rax
        movq    %rax, -40(%rbp)
        movsd   -40(%rbp), %xmm0
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   add, .-add
        .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
        .section        .note.GNU-stack,"",@progbits

.file "exp1.c"
.comm a,8,8
.comm b,8,8
.comm c,8,8
.section .rodata
.LC2:
.string "\n%lf"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $48, %rsp
movabsq $4607632778762754458, %rax
movq %rax, -24(%rbp)
movabsq $4611911198408756429, %rax
movq %rax, -16(%rbp)
leaq -8(%rbp), %rax
movq %rax, c(%rip)
leaq -24(%rbp), %rax
movq %rax, a(%rip)
leaq -16(%rbp), %rax
movq %rax, b(%rip)
movq c(%rip), %rax
movq a(%rip), %rdx
movsd (%rdx), %xmm1
movq b(%rip), %rdx
movsd (%rdx), %xmm0
#addsd %xmm1, %xmm0            # commented actual addition
call add                       # added my library call here
movsd %xmm0, (%rax)            # segmentation fault here
movq c(%rip), %rax
movq (%rax), %rax
movq %rax, -40(%rbp)
movsd -40(%rbp), %xmm0
movl $.LC2, %edi
movl $1, %eax
call printf
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
  • The `add` function clobbers `%rax`, so storing into `(%rax)` segfaults. Use a debugger to single-step. – Peter Cordes Nov 23 '17 at 07:39
  • You don't need to store and reload the return value in `%xmm0`. You're just making things complicated for yourself by using un-optimized compiler output. Compile with `-O2`. See also https://stackoverflow.com/questions/38552116/how-to-remove-noise-from-gcc-clang-assembly-output, especially the link to Matt Godbolt's talk about looking at compiler output. – Peter Cordes Nov 23 '17 at 07:42
  • @PeterCordes I am not allowed to use optimization flags, add.c is a kind of third party lib, I need to invoke that lib call from gcc generated assembly – vinay kumar Maddala Nov 23 '17 at 08:51
  • Ok, then optimize the asm by hand yourself and remove the useless store/reload. Is there some kind of requirement that the asm has to "look like" the source, instead of just producing the same result using any optimizations the "as-if" rule would let a compiler make? You are allowed to optimize out the store/reload, right? Because nothing in the C source depends on having `*c` in memory; a register is fine. – Peter Cordes Nov 23 '17 at 10:23
  • Or if that's not ok, then use a call-preserved register like `%rbx` for `double *c`. (Don't forget to save/restore it so `main` doesn't clobber its caller's value). – Peter Cordes Nov 23 '17 at 10:26

0 Answers0