user: Please show me the C implementation that matches the assembly code listed below:

```asm
<heapsort>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  add    $0xffffffffffffff80,%rsp
  mov    %rdi,-0x68(%rbp)
  mov    %rsi,-0x70(%rbp)
  mov    %rdx,-0x78(%rbp)
  mov    %rcx,-0x80(%rbp)
  cmpq   $0x1,-0x70(%rbp)
  ja     L184
  mov    $0x0,%eax
  jmp    L213
L184:
  cmpq   $0x0,-0x78(%rbp)
  jne    L241
  mov    D6(%rip),%rax
  mov    (%rax),%edx
  mov    D11(%rip),%rax
  mov    %edx,(%rax)
  mov    $0xffffffff,%eax
  jmp    L213
L241:
  mov    -0x78(%rbp),%rax
  mov    %rax,%rdi
  call   <malloc@plt>
  mov    %rax,-0x10(%rbp)
  cmpq   $0x0,-0x10(%rbp)
  jne    L151
  mov    $0xffffffff,%eax
  jmp    L213
L151:
  mov    -0x78(%rbp),%rax
  neg    %rax
  mov    %rax,%rdx
  mov    -0x68(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x70(%rbp),%rax
  shr    %rax
  add    $0x1,%rax
  mov    %rax,-0x38(%rbp)
  jmp    L53
L179:
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x48(%rbp)
  jmp    L158
L247:
  mov    -0x40(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x40(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  jae    L114
  mov    -0x20(%rbp),%rdx
  mov    -0x78(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x20(%rbp),%rax
  mov    -0x80(%rbp),%rdx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   *%rdx
  test   %eax,%eax
  jns    L114
  mov    -0x78(%rbp),%rax
  add    %rax,-0x20(%rbp)
  addq   $0x1,-0x40(%rbp)
L114:
  mov    -0x48(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  mov    -0x80(%rbp),%rcx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   *%rcx
  test   %eax,%eax
  jg     L118
  jmp    L53
L118:
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x50(%rbp)
L221:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x51(%rbp)
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  mov    -0x20(%rbp),%rdx
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  mov    -0x20(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x20(%rbp)
  movzbl -0x51(%rbp),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x50(%rbp)
  cmpq   $0x0,-0x50(%rbp)
  jne    L221
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x48(%rbp)
L158:
  mov    -0x48(%rbp),%rax
  add    %rax,%rax
  mov    %rax,-0x40(%rbp)
  mov    -0x40(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  jbe    L247
L53:
  subq   $0x1,-0x38(%rbp)
  cmpq   $0x0,-0x38(%rbp)
  jne    L179
  jmp    L167
L258:
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x10(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x70(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x28(%rbp)
L50:
  mov    -0x28(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x30(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x50(%rbp)
  cmpq   $0x0,-0x50(%rbp)
  jne    L50
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x70(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x78(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x28(%rbp)
L298:
  mov    -0x28(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x30(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x50(%rbp)
  cmpq   $0x0,-0x50(%rbp)
  jne    L298
  subq   $0x1,-0x70(%rbp)
  movq   $0x1,-0x48(%rbp)
  jmp    L266
L261:
  mov    -0x40(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x40(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  jae    L248
  mov    -0x20(%rbp),%rdx
  mov    -0x78(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x20(%rbp),%rax
  mov    -0x80(%rbp),%rdx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   *%rdx
  test   %eax,%eax
  jns    L248
  mov    -0x78(%rbp),%rax
  add    %rax,-0x20(%rbp)
  addq   $0x1,-0x40(%rbp)
L248:
  mov    -0x48(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x28(%rbp)
L111:
  mov    -0x28(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x30(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x50(%rbp)
  cmpq   $0x0,-0x50(%rbp)
  jne    L111
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x48(%rbp)
L266:
  mov    -0x48(%rbp),%rax
  add    %rax,%rax
  mov    %rax,-0x40(%rbp)
  mov    -0x40(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  jbe    L261
L244:
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x40(%rbp)
  mov    -0x40(%rbp),%rax
  shr    %rax
  mov    %rax,-0x48(%rbp)
  mov    -0x40(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x48(%rbp),%rax
  imul   -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x18(%rbp)
  cmpq   $0x1,-0x40(%rbp)
  je     L142
  mov    -0x18(%rbp),%rdx
  mov    -0x10(%rbp),%rax
  mov    -0x80(%rbp),%rcx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   *%rcx
  test   %eax,%eax
  jns    L79
L142:
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x10(%rbp),%rax
  mov    %rax,-0x28(%rbp)
L198:
  mov    -0x28(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x30(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x50(%rbp)
  cmpq   $0x0,-0x50(%rbp)
  jne    L198
  jmp    L167
L79:
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x28(%rbp)
L226:
  mov    -0x28(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x30(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x50(%rbp)
  cmpq   $0x0,-0x50(%rbp)
  jne    L226
  jmp    L244
L167:
  cmpq   $0x1,-0x70(%rbp)
  ja     L258
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    $0x0,%eax
L213:
  leave
  ret
```

assistant: ```c
int heapsort(void *vbase, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
  size_t cnt, i, j, l;
  char tmp, *tmp1, *tmp2;
  char *base, *k, *p, *t;
  if (nmemb <= 1)
    return (0);
  if (!size) {
    errno = EINVAL;
    return (-1);
  }
  if ((k = malloc(size)) == NULL)
    return (-1);
  base = (char *)vbase - size;
  for (l = nmemb / 2 + 1; --l;) {
    for (i = l; (j = i * 2) <= nmemb; i = j) {
      p = base + j * size;
      if (j < nmemb && compar(p, p + size) < 0) {
        p += size;
        ++j;
      }
      t = base + i * size;
      if (compar(p, t) <= 0)
        break;
      {
        cnt = size;
        do {
          tmp = *t;
          *t++ = *p;
          *p++ = tmp;
        } while (--cnt);
      };
    }
  };
  while (nmemb > 1) {
    {
      cnt = size;
      tmp1 = k;
      tmp2 = base + nmemb * size;
      do {
        *tmp1++ = *tmp2++;
      } while (--cnt);
    };
    {
      cnt = size;
      tmp1 = base + nmemb * size;
      tmp2 = base + size;
      do {
        *tmp1++ = *tmp2++;
      } while (--cnt);
    };
    --nmemb;
    {
      for (i = 1; (j = i * 2) <= nmemb; i = j) {
        p = base + j * size;
        if (j < nmemb && compar(p, p + size) < 0) {
          p += size;
          ++j;
        }
        t = base + i * size;
        {
          cnt = size;
          tmp1 = t;
          tmp2 = p;
          do {
            *tmp1++ = *tmp2++;
          } while (--cnt);
        };
      }
      for (;;) {
        j = i;
        i = j / 2;
        p = base + j * size;
        t = base + i * size;
        if (j == 1 || compar(k, t) < 0) {
          {
            cnt = size;
            tmp1 = p;
            tmp2 = k;
            do {
              *tmp1++ = *tmp2++;
            } while (--cnt);
          };
          break;
        }
        {
          cnt = size;
          tmp1 = p;
          tmp2 = t;
          do {
            *tmp1++ = *tmp2++;
          } while (--cnt);
        };
      }
    };
  }
  free(k);
  return (0);
}
```