assembly function with C segfault

330 views Asked by At

I am trying to make assembly function that uses SSE and FPU for parallel calculations. Unfortunately I am receiving segmentation fault(core dumped) error(while debugging it doesn't show in assembly function). I also cannot step out from assembly function. Gdb shows:

Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x2bffff

after ret statement. I'm out of any ideas what may cause that type of behaviour. Maybe some of you see something I don't? Cheers.

Integrals.s

#float intgr_vert(float x)
#{
#   return pow(x, 2) - 4*x + 6;
#}

s_precision = 0x007f

.bss
    .lcomm holder, 4
    .lcomm  rect_size_vec, 16
    .lcomm  x_vec, 16
    .lcomm  result, 16

.data
four:
    .float 4.0, 4.0, 4.0, 4.0
six:
    .float 6.0, 6.0, 6.0, 6.0

.globl four_intgr_strips

.type four_intgr_strips, @function
four_intgr_strips:

pushl %eax
pushl %ecx
pushl %edx
pushl %ebp
movl  %esp, %ebp

subl $2, %esp  

movl $0, %edi
movl 20(%ebp),  %eax    #x position
movl 24(%ebp), %ebx #rectangle size
movw $s_precision, -2(%ebp)

finit

fldcw -2(%ebp)

pool:
movl %eax, x_vec(, %edi, 4)
movl %ebx, rect_size_vec(, %edi, 4)

movl %eax, holder
flds holder
movl %ebx, holder
flds holder     #adding size of rectangle to calculate different x
fadd %st(1), %st(0)
fstps holder
movl holder, %eax

inc %edi
cmp $4, %edi
je pool_dne
jmp pool

pool_dne:


ret ###########################can't go further

.type sumAreas, @function
sumAreas:
movl $0, %edi

flds result(, %edi, 4)
inc %edi

loop:
flds result(, %edi, 4)
fadd %st(1), %st(0)
inc %edi
cmp $4, %edi
je end_loop
jmp loop

end_loop:


ret

.type calcAreas, @function
calcAreas:

movaps rect_size_vec, %xmm1
mulps %xmm1, %xmm0
movaps %xmm0, result

ret

.type calcVertical, @function
calcVertical:

movaps x_vec, %xmm0
mulps %xmm0, %xmm0
movaps x_vec, %xmm1
movups four, %xmm2
mulps %xmm1, %xmm2
subps %xmm2, %xmm0
movups six, %xmm1
addps %xmm1, %xmm0

ret

main.c

#include <stdio.h>
#include <math.h>

// x^2 - 4x + 6 integral

float four_intgr_strips(float, float);


float calc_intgr_in_as(int a, int n, float rect_size)
{
    float sum = 0;
    float four_rect_area;
    float last_rect_l_corner = a;

for(int i = 0; i != n/4; i++)
{
        four_rect_area = four_intgr_strips(last_rect_l_corner, rect_size);
        sum = sum + four_rect_area;
        last_rect_l_corner = last_rect_l_corner + 4*rect_size;
    }


return sum;
}

int main()
{
    int a, b, n;
    float rect_size;
    float sum;

    printf("\nType integral lower bound:");
    scanf("%d", &a);
    printf("\nType integral upper bound:");

 scanf("%d", &b);
    do
    {
        printf("\nType rectangles number(must be multiple of 4):");
        scanf("%d", &n);
    }
    while(n % 4 != 0);

    rect_size = (float)(b - a)/n;

    sum = calc_intgr_in_as(a, n, rect_size);
    printf("\nArea under function is: %f with SSE", sum);
}
1

There are 1 answers

1
Jester On BEST ANSWER

You have forgotten to cleanup the stack. In the prologue you have:

pushl %eax
pushl %ecx
pushl %edx
pushl %ebp
movl  %esp, %ebp

You obviously need to undo that before you ret, such as:

movl %ebp, %esp
popl %ebp
popl %edx
popl %ecx
popl %eax
ret

PS: I have already told you that unaligning the stack is a bad idea, sooner or later that will bite you. Also, next time you ask a question, mention what input you used and what output you expect.