user: 请从给定的汇编指令推导出C源代码：

```asm
<freecell_solver_merge_large_and_small_sorted_arrays>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  add    $0xffffffffffffff80,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %rdx,-0x58(%rbp)
  mov    %rcx,-0x60(%rbp)
  mov    %r8,-0x68(%rbp)
  mov    %r9,-0x70(%rbp)
  mov    0x10(%rbp),%rax
  mov    %rax,-0x78(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x58(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  movl   $0x0,-0x30(%rbp)
  mov    -0x60(%rbp),%rax
  sub    $0x1,%eax
  mov    %eax,-0x34(%rbp)
  jmp    L0
L18:
  mov    -0x30(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x50(%rbp),%rax
  sub    %rdx,%rax
  mov    %rax,%rsi
  mov    -0x34(%rbp),%eax
  cltq
  imul   -0x68(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rdi
  mov    -0x78(%rbp),%r9
  mov    -0x70(%rbp),%r8
  mov    -0x68(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  sub    $0x8,%rsp
  lea    -0x38(%rbp),%rcx
  push   %rcx
  mov    %rdx,%rcx
  mov    %rsi,%rdx
  mov    %rax,%rsi
  call   <freecell_solver_bsearch@plt>
  add    $0x10,%rsp
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rax
  sub    -0x20(%rbp),%rax
  mov    $0x0,%edx
  divq   -0x68(%rbp)
  mov    %eax,-0x2c(%rbp)
  mov    -0x50(%rbp),%rax
  mov    %eax,%edx
  mov    -0x60(%rbp),%rax
  add    %edx,%eax
  mov    -0x30(%rbp),%edx
  sub    %edx,%eax
  mov    %eax,%ecx
  mov    -0x34(%rbp),%eax
  mov    -0x60(%rbp),%rdx
  sub    %edx,%eax
  add    %ecx,%eax
  add    $0x1,%eax
  mov    %eax,-0x28(%rbp)
  mov    -0x28(%rbp),%edx
  mov    -0x2c(%rbp),%eax
  add    %edx,%eax
  mov    %eax,%ecx
  mov    -0x30(%rbp),%eax
  mov    -0x50(%rbp),%rdx
  sub    %edx,%eax
  add    %ecx,%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x28(%rbp),%eax
  sub    -0x24(%rbp),%eax
  cltq
  mov    %eax,%edx
  mov    -0x68(%rbp),%rax
  imul   %edx,%eax
  mov    %eax,%edx
  mov    -0x2c(%rbp),%eax
  cltq
  imul   -0x68(%rbp),%rax
  mov    %rax,%rcx
  mov    -0x20(%rbp),%rax
  add    %rax,%rcx
  mov    -0x24(%rbp),%eax
  cltq
  imul   -0x68(%rbp),%rax
  mov    %rax,%rsi
  mov    -0x20(%rbp),%rax
  add    %rsi,%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memmove@plt>
  mov    -0x34(%rbp),%eax
  cltq
  imul   -0x68(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rsi
  mov    -0x24(%rbp),%eax
  sub    $0x1,%eax
  cltq
  imul   -0x68(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x68(%rbp),%rax
  mov    %rax,%rdx
  mov    %rcx,%rdi
  call   <memcpy@plt>
  mov    -0x28(%rbp),%eax
  sub    -0x24(%rbp),%eax
  add    %eax,-0x30(%rbp)
  subl   $0x1,-0x34(%rbp)
L0:
  cmpl   $0x0,-0x34(%rbp)
  jns    L18
  mov    $0x1,%eax
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L10
  call   <__stack_chk_fail@plt>
L10:
  leave
  ret
```

assistant: ```c
int freecell_solver_merge_large_and_small_sorted_arrays(void *void_big_array, size_t size_big_array, void *void_small_array, size_t size_small_array, size_t width, int (*compare)(const void *, const void *, void *), void *context) {
  int item_to_move, num_big_items_moved, pos;
  char *pos_ptr;
  char *big_array;
  char *small_array;
  int found;
  int start_offset, end_offset;
  big_array = (char *)void_big_array;
  small_array = (char *)void_small_array;
  num_big_items_moved = 0;
  for (item_to_move = size_small_array - 1; item_to_move >= 0; item_to_move--) {
    pos_ptr = freecell_solver_bsearch(small_array + item_to_move * width, big_array, size_big_array - num_big_items_moved, width, compare, context, &found);
    pos = (pos_ptr - big_array) / width;
    end_offset = size_big_array + size_small_array - num_big_items_moved - (size_small_array - item_to_move - 1);
    start_offset = end_offset + pos - (size_big_array - num_big_items_moved);
    memmove(big_array + start_offset * width, big_array + pos * width, (end_offset - start_offset) * width);
    memcpy(big_array + (start_offset - 1) * width, small_array + item_to_move * width, width);
    num_big_items_moved += (end_offset - start_offset);
  }
  return 1;
}
```