2015-06-15 24 views
0

我正在嘗試使用SSE和FPU進行並行計算的彙編函數。不幸的是,我收到了segmentation fault(core dumped)錯誤(在調試時它不顯示彙編函數)。我也不能從彙編函數中退出。 Gdb顯示:用C語言裝配函數segfault

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

ret語句後。 我沒有任何想法可能會導致此類行爲。也許你們中的一些人看到我不喜歡的東西?乾杯。

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); 
} 
+0

我不喜歡sum = 0(而不是0.0),但取決於編譯器,這可能是好的。 – Jiminion

+0

@ Jiminion:強制規則。標準沒關係。 (但我同意,我也有一種習慣,把花車寫成花車。) – Olaf

回答

4

你忘了清理棧。 在序言您有:

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

你顯然需要撤消您ret之前,如:

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

PS:我已經告訴過你,unaligning堆棧是一個壞主意,遲早會咬你。另外,下次您提出問題時,請提及您使用的輸入內容以及您期望的輸出內容。

+0

哦,那簡直太棒了!我只是忘了這個.. 我也讀過關於對齊剛纔。我現在看到你的建議是對的。 並感謝您的建議提前! – Robs