Calling an assembly function from C

别等时光非礼了梦想. 提交于 2021-02-10 07:44:45

问题


One of my generated functions doesn't compute what it should and I am trying to debug it separately. I have the assembler for it and I try to call it from a stripped down C program. However, for some reason I end up getting segfaults in the function (so, calling the function seems to work, but execution fails). There might be something wrong with passing the arguments..

The functions signature is

void func(int, int, float*, float*, float*);

The function ignores the first two arguments and received 3 arrays of 32 floats each. It would add element-wise the latter two and store the result element-wise into the first array. However, it would do that in a kind of weird order (as opposed to streaming linearly through it, the reason for doing this is not in the scope of this SO question). That's what the offset_arrays are for in the assembler code.

I checked the x86 calling conventions (that's the architecture I am using) and the first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, and R9.

Here' the function implementation:

    .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

I try to call the function from this C code:

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

Compiling both and linking with

gcc -o f.o -c -g f.S
gcc -g -o test_f test_f.c f.o

and running though gdb results in

Program received signal SIGSEGV, Segmentation fault.
func () at f.S:17
17      movss   %xmm0, (%rdx,%r11,4)

So, this is obviously a write to memory, namely to the first array. Why would it segfault and how to call this function correctly (without changing the assembler code)?


回答1:


The problem comes from this line

cmpq    $33, %rsi

it should be

cmpq    $32, %rsi

you are accessing the junk in the memory after .quad 31 and sticking that into r11 at movq (%r9,%rax), %r11




回答2:


The size of the arrays is 32, but in the function the %rsi is incrementing from 0 to 33 with jb after it. It is wrong and access this part of static memory(not allocated) raieses a segmentation fault. It should be changed to 32. Tested in 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


来源:https://stackoverflow.com/questions/31548364/calling-an-assembly-function-from-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!