带有 C 段错误的汇编函数
assembly function with C segfault
我正在尝试制作使用 SSE 和 FPU 进行并行计算的汇编函数。不幸的是,我收到 segmentation fault(core dumped)
错误(调试时它没有显示在汇编函数中)。我也无法退出汇编功能。 Gdb 显示:
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 , %esp
movl [=11=], %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 , %edi
je pool_dne
jmp pool
pool_dne:
ret ###########################can't go further
.type sumAreas, @function
sumAreas:
movl [=11=], %edi
flds result(, %edi, 4)
inc %edi
loop:
flds result(, %edi, 4)
fadd %st(1), %st(0)
inc %edi
cmp , %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);
}
您忘记清理堆栈了。
在序言中你有:
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:我已经告诉过你,不对齐堆栈是个坏主意,迟早会害了你。此外,下次您提问时,请提及您使用的输入以及您期望的输出。
我正在尝试制作使用 SSE 和 FPU 进行并行计算的汇编函数。不幸的是,我收到 segmentation fault(core dumped)
错误(调试时它没有显示在汇编函数中)。我也无法退出汇编功能。 Gdb 显示:
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 , %esp
movl [=11=], %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 , %edi
je pool_dne
jmp pool
pool_dne:
ret ###########################can't go further
.type sumAreas, @function
sumAreas:
movl [=11=], %edi
flds result(, %edi, 4)
inc %edi
loop:
flds result(, %edi, 4)
fadd %st(1), %st(0)
inc %edi
cmp , %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);
}
您忘记清理堆栈了。 在序言中你有:
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:我已经告诉过你,不对齐堆栈是个坏主意,迟早会害了你。此外,下次您提问时,请提及您使用的输入以及您期望的输出。