user: 请显示与下面列出的汇编代码相匹配的C语言实现:

```asm
<cbssort>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  mov    %edx,%r13d
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x68,%rsp
  mov    %rdi,0x38(%rsp)
  mov    %esi,0x48(%rsp)
  mov    %rcx,0x8(%rsp)
  test   %rdi,%rdi
  je     L17
  test   %esi,%esi
  js     L17
  test   %edx,%edx
  setg   %al
  xor    %edi,%edi
  test   %rcx,%rcx
  setne  %dil
  and    %eax,%edi
  call   <assert@plt>
  mov    %r13d,%edi
  call   <malloc@plt>
  mov    %rax,%r14
  test   %rax,%rax
  je     L97
L101:
  mov    0x48(%rsp),%eax
  lea    -0x1(%rax),%edx
  movslq %edx,%rax
  sar    $0x1f,%edx
  imul   $0x55555556,%rax,%rax
  shr    $0x20,%rax
  mov    %eax,%r15d
  mov    %r14,%rax
  sub    %edx,%r15d
  mov    %r15d,%r14d
  mov    %rax,%r15
L169:
  cmp    $0x4,%r14d
  mov    $0x1,%eax
  movl   $0x0,0x58(%rsp)
  cmovle %eax,%r14d
  mov    %r14d,%ebx
  lea    (%r14,%r14,1),%eax
  mov    %r14d,0x50(%rsp)
  imul   %r13d,%ebx
  mov    %eax,0x5c(%rsp)
  movslq %ebx,%rax
  mov    %ebx,0x4c(%rsp)
  mov    %rax,0x40(%rsp)
  mov    %ebx,%eax
  neg    %eax
  mov    %ebx,0x54(%rsp)
  cltq
  mov    %rax,0x28(%rsp)
  nopl   0x0(%rax,%rax,1)
L60:
  movslq 0x58(%rsp),%rbx
  mov    0x50(%rsp),%eax
  mov    %rbx,0x18(%rsp)
  movslq 0x54(%rsp),%rbx
  mov    %eax,0x30(%rsp)
  mov    %rbx,0x10(%rsp)
  mov    %ebx,0x34(%rsp)
  cmp    %eax,0x48(%rsp)
  jg     L35
  jmp    L94
  nopl   0x0(%rax,%rax,1)
L6:
  mov    0x40(%rsp),%rdx
  add    %r14d,0x30(%rsp)
  mov    0x4c(%rsp),%esi
  add    %rdx,0x18(%rsp)
  add    %rdx,0x10(%rsp)
  mov    0x30(%rsp),%eax
  add    %esi,0x34(%rsp)
  cmp    %eax,0x48(%rsp)
  jle    L94
L35:
  mov    0x38(%rsp),%rax
  mov    0x10(%rsp),%r12
  mov    0x18(%rsp),%rdi
  add    %rax,%r12
  add    %rax,%rdi
  mov    %r12,%rsi
  mov    0x8(%rsp),%rax
  call   *%rax
  test   %eax,%eax
  jle    L6
  mov    %r13d,%edx
  mov    %r12,%rsi
  mov    %r15,%rdi
  call   <memcpy@plt>
  mov    0x30(%rsp),%ebx
  cmp    %ebx,%r14d
  jg     L154
  mov    0x38(%rsp),%rax
  movslq 0x34(%rsp),%r8
  lea    (%rax,%r8,1),%r12
  mov    0x18(%rsp),%rax
  sub    0x10(%rsp),%rax
  mov    %rax,0x20(%rsp)
  mov    %r12,%rbp
  jmp    L4
  cs nopw 0x0(%rax,%rax,1)
L177:
  mov    %rbp,%rdi
  mov    %r13d,%edx
  mov    %r12,%rsi
  call   <memcpy@plt>
  add    0x28(%rsp),%rbp
  cmp    %r14d,%ebx
  jl     L154
L4:
  mov    0x20(%rsp),%rax
  sub    %r14d,%ebx
  mov    %r15,%rsi
  lea    (%rax,%rbp,1),%r12
  mov    0x8(%rsp),%rax
  mov    %r12,%rdi
  call   *%rax
  test   %eax,%eax
  jns    L177
  mov    %rbp,%r12
L154:
  mov    %r13d,%edx
  mov    %r15,%rsi
  mov    %r12,%rdi
  call   <memcpy@plt>
  jmp    L6
L17:
  xor    %edi,%edi
  call   <assert@plt>
  mov    %r13d,%edi
  call   <malloc@plt>
  mov    %rax,%r14
  test   %rax,%rax
  je     L97
L8:
  cmpl   $0xffffffff,0x48(%rsp)
  jge    L101
L162:
  add    $0x68,%rsp
  mov    %r14,%rdi
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1090 <free@plt>
  nopl   0x0(%rax,%rax,1)
L94:
  addl   $0x1,0x50(%rsp)
  mov    0x50(%rsp),%eax
  add    %r13d,0x54(%rsp)
  add    %r13d,0x58(%rsp)
  cmp    0x5c(%rsp),%eax
  jne    L60
  cmp    $0x1,%r14d
  je     L16
  lea    -0x1(%r14),%eax
  mov    $0xaaaaaaab,%ecx
  imul   %rcx,%rax
  shr    $0x21,%rax
  mov    %rax,%r14
  jmp    L169
L97:
  lea    D1(%rip),%rdi
  xor    %r14d,%r14d
  call   <cbmyfatal@plt>
  jmp    L8
L16:
  mov    %r15,%r14
  jmp    L162
```

tool_calls: name: unpack_data
arguments: data_tag: D1
type_infered: string

tool: D1: out of memory

assistant: ```c
void cbssort(void *base, int nmemb, int size, int (*compar)(const void *, const void *)) {
  char *bp, *swap;
  int step, bottom, i, j;
  assert(base && nmemb >= 0 && size > 0 && compar);
  bp = (char *)base;
  (((swap) = malloc(size)) ? (swap) : cbmyfatal("out of memory"));
  for (step = (nmemb - 1) / 3; step >= 0; step = (step - 1) / 3) {
    if (step < 5)
      step = 1;
    for (bottom = 0; bottom < step; bottom++) {
      for (i = bottom + step; i < nmemb; i += step) {
        if (compar(bp + (i - step) * size, bp + i * size) > 0) {
          memcpy(swap, bp + i * size, size);
          for (j = i; j > step - 1; j -= step) {
            if (compar(bp + (j - step) * size, swap) < 0)
              break;
            memcpy(bp + j * size, bp + (j - step) * size, size);
          }
          memcpy(bp + j * size, swap, size);
        }
      }
    }
    if (step < 2)
      break;
  }
  free(swap);
}
```