我生成的一个函数没有计算它应该是什么,我试图单独调试它。我有它的汇编程序,我试图从一个剥离的C程序调用它。但是,出于某种原因,我最终在函数中获得了段错误(因此,调用函数似乎工作,但执行失败)。传递参数可能有问题。
功能签名是
void func(int, int, float*, float*, float*);
该函数忽略前两个参数,并接收3个32个浮点数的数组。它会在元素方面添加后两者并将结果按元素存储到第一个数组中。但是,它会以一种奇怪的顺序(而不是线性流过它,这样做的原因不在于这个SO问题的范围内)。这就是汇编代码中offset_arrays
的用途。
我检查了x86调用约定(这是我正在使用的架构),前六个整数或指针参数在寄存器RDI,RSI,RDX,RCX,R8和R9中传递。
这里是功能实现:
.text
.globl func
.align 16, 0x90
.type func,@function
func:
.cfi_startproc
xorl %eax, %eax
movabsq $offset_array1, %r9
movabsq $offset_array, %r10
xorl %esi, %esi
.align 16, 0x90
.LBB0_1:
movq (%r9,%rax), %r11
movq (%r10,%rax), %rdi
movss (%r8,%rdi,4), %xmm0
addss (%rcx,%rdi,4), %xmm0
movss %xmm0, (%rdx,%r11,4)
incq %rsi
addq $8, %rax
cmpq $33, %rsi
jb .LBB0_1
retq
.Ltmp0:
.size func, .Ltmp0-func
.cfi_endproc
.type offset_array,@object
.section .rodata,"a",@progbits
.align 16
offset_array:
.quad 0
.quad 16
.quad 1
.quad 17
.quad 2
.quad 18
.quad 3
.quad 19
.quad 4
.quad 20
.quad 5
.quad 21
.quad 6
.quad 22
.quad 7
.quad 23
.quad 8
.quad 24
.quad 9
.quad 25
.quad 10
.quad 26
.quad 11
.quad 27
.quad 12
.quad 28
.quad 13
.quad 29
.quad 14
.quad 30
.quad 15
.quad 31
.size offset_array, 256
.type offset_array1,@object
.align 16
offset_array1:
.quad 0
.quad 16
.quad 1
.quad 17
.quad 2
.quad 18
.quad 3
.quad 19
.quad 4
.quad 20
.quad 5
.quad 21
.quad 6
.quad 22
.quad 7
.quad 23
.quad 8
.quad 24
.quad 9
.quad 25
.quad 10
.quad 26
.quad 11
.quad 27
.quad 12
.quad 28
.quad 13
.quad 29
.quad 14
.quad 30
.quad 15
.quad 31
.size offset_array1, 256
.section ".note.GNU-stack","",@progbits
我尝试从这个C代码调用函数:
float f0[32];
float f1[32];
float f2[32];
extern void func(int i0,int i1,float* dest,float* src0,float* src1);
int main(int argc, char *argv[])
{
func(0,0,f0,f1,f2);
}
编译两者并与
链接gcc -o f.o -c -g f.S
gcc -g -o test_f test_f.c f.o
并通过gdb运行
Program received signal SIGSEGV, Segmentation fault.
func () at f.S:17
17 movss %xmm0, (%rdx,%r11,4)
所以,这显然是对内存的写入,即对第一个数组的写入。为什么会出现段错误以及如何正确调用此函数(不更改汇编代码)?
答案 0 :(得分:2)
数组的大小为32,但在函数中,%rsi
从0增加到33,后跟jb
。这是错误的,访问静态内存的这部分(未分配)会引发分段错误。它应该更改为32.在ubuntu中测试。
func:
.cfi_startproc
xorl %eax, %eax
movabsq $offset_array1, %r9
movabsq $offset_array, %r10
xorl %esi, %esi
.align 16, 0x90
.LBB0_1:
movq (%r9,%rax), %r11
movq (%r10,%rax), %rdi
movss (%r8,%rdi,4), %xmm0
addss (%rcx,%rdi,4), %xmm0
movss %xmm0, (%rdx,%r11,4)
incq %rsi
addq $8, %rax
cmpq $32, %rsi
jb .LBB0_1
答案 1 :(得分:2)
问题来自这一行
cmpq $33, %rsi
应该是
cmpq $32, %rsi
您正在.quad 31
之后访问内存中的垃圾并将其粘贴到movq (%r9,%rax), %r11