user: Converte this assembly snippet into its equivalent C code:

```asm
<sulong_qsort>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %rcx,-0x30(%rbp)
  mov    %r8,-0x38(%rbp)
  mov    %r9,-0x40(%rbp)
  mov    -0x28(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jge    L8
  mov    -0x28(%rbp),%rdx
  mov    -0x30(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,%rdx
  shr    $0x3f,%rdx
  add    %rdx,%rax
  sar    %rax
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rdi
  mov    -0x28(%rbp),%rax
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rsi
  mov    -0x40(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  mov    %rdx,%rcx
  mov    %rdi,%rdx
  mov    %rax,%rdi
  call   <sulong_swap@plt>
  mov    -0x28(%rbp),%rax
  mov    %eax,-0x4(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x1,%eax
  mov    %eax,-0x8(%rbp)
  jmp    L5
L17:
  mov    -0x28(%rbp),%rax
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x8(%rbp),%eax
  cltq
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  add    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rdx,%rdi
  call   *%rax
  test   %eax,%eax
  jns    L30
  addl   $0x1,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  cltq
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rdi
  mov    -0x4(%rbp),%eax
  cltq
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rsi
  mov    -0x40(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  mov    %rdx,%rcx
  mov    %rdi,%rdx
  mov    %rax,%rdi
  call   <sulong_swap@plt>
L30:
  addl   $0x1,-0x8(%rbp)
L5:
  mov    -0x8(%rbp),%eax
  cltq
  cmp    %rax,-0x30(%rbp)
  jge    L17
  mov    -0x4(%rbp),%eax
  cltq
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rdi
  mov    -0x28(%rbp),%rax
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x20(%rbp),%rax
  lea    (%rdx,%rax,1),%rsi
  mov    -0x40(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  mov    %rdx,%rcx
  mov    %rdi,%rdx
  mov    %rax,%rdi
  call   <sulong_swap@plt>
  mov    -0x4(%rbp),%eax
  sub    $0x1,%eax
  movslq %eax,%rcx
  mov    -0x40(%rbp),%r8
  mov    -0x38(%rbp),%rdi
  mov    -0x28(%rbp),%rdx
  mov    -0x20(%rbp),%rsi
  mov    -0x18(%rbp),%rax
  mov    %r8,%r9
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <sulong_qsort>
  mov    -0x4(%rbp),%eax
  add    $0x1,%eax
  movslq %eax,%rdx
  mov    -0x40(%rbp),%r8
  mov    -0x38(%rbp),%rdi
  mov    -0x30(%rbp),%rcx
  mov    -0x20(%rbp),%rsi
  mov    -0x18(%rbp),%rax
  mov    %r8,%r9
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <sulong_qsort>
  jmp    L48
L8:
  nop
L48:
  leave
  ret
```

assistant: ```c
void sulong_qsort(char *buffer, char *v, long left, long right, int (*comp)(const void *, const void *), size_t size) {
  int i, last;
  if (left >= right) {
    return;
  }
  sulong_swap(buffer, &v[left * size], &v[((left + right) / 2) * size], size);
  last = left;
  for (i = left + 1; i <= right; i++) {
    if (comp(&(v[i * size]), &(v[left * size])) < 0) {
      last++;
      sulong_swap(buffer, &(v[last * size]), &(v[i * size]), size);
    }
  }
  sulong_swap(buffer, &(v[left * size]), &(v[last * size]), size);
  sulong_qsort(buffer, v, left, last - 1, comp, size);
  sulong_qsort(buffer, v, last + 1, right, comp, size);
}
```