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

```asm
<heap>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %rdi,%rbp
  push   %rbx
  mov    %esi,%ebx
  sub    $0x18,%rsp
L7:
  cmp    $0x2,%ebx
  je     L13
  jg     L69
  cmp    $0x1,%ebx
  ja     L56
L85:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  cs nopw 0x0(%rax,%rax,1)
L69:
  cmp    $0x3,%ebx
  jne    L88
  add    $0x18,%rsp
  lea    0x8(%rbp),%rdx
  lea    0x4(%rbp),%rsi
  mov    %rbp,%rdi
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    10d0 <sort3@plt>
  nopl   0x0(%rax,%rax,1)
L13:
  add    $0x18,%rsp
  lea    0x4(%rbp),%rsi
  mov    %rbp,%rdi
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    10a0 <sort2@plt>
  nopw   0x0(%rax,%rax,1)
L88:
  lea    0x0(,%rbx,4),%r13d
  lea    -0x1(%rbx),%r15d
  xor    %r12d,%r12d
  mov    %r13d,%edi
  call   <malloc@plt>
  mov    %r13d,%edx
  mov    %rbp,%rsi
  mov    %rax,%rdi
  mov    %rax,%r14
  call   <memcpy@plt>
  lea    -0x2(%rbx),%edx
  mov    0x0(%rbp),%ecx
  lea    0x4(%rbp),%rax
  mov    %edx,0x4(%rsp)
  lea    0x8(%rbp,%rdx,4),%rsi
  jmp    L84
  nopl   (%rax)
L103:
  movslq %r12d,%rdi
  add    $0x4,%rax
  add    $0x1,%r12d
  mov    %edx,(%r14,%rdi,4)
  cmp    %rax,%rsi
  je     L73
L84:
  mov    (%rax),%edx
  cmp    %edx,%ecx
  jg     L103
  movslq %r15d,%rdi
  add    $0x4,%rax
  sub    $0x1,%r15d
  mov    %edx,(%r14,%rdi,4)
  cmp    %rax,%rsi
  jne    L84
L73:
  movslq %r12d,%r8
  mov    %r13d,%edx
  mov    %r14,%rsi
  mov    %rbp,%rdi
  mov    %ecx,(%r14,%r8,4)
  mov    %r8,0x8(%rsp)
  call   <memcpy@plt>
  mov    %r14,%rdi
  call   <free@plt>
  cmp    $0x1,%r12d
  mov    0x8(%rsp),%r8
  jg     L124
L121:
  cmp    %r15d,0x4(%rsp)
  jle    L85
  sub    %r12d,%ebx
  lea    0x4(%rbp,%r8,4),%rbp
  sub    $0x1,%ebx
  jmp    L7
  xchg   %ax,%ax
L124:
  mov    %r12d,%esi
  mov    %rbp,%rdi
  call   <heap>
  mov    0x8(%rsp),%r8
  jmp    L121
  nopw   0x0(%rax,%rax,1)
L56:
  lea    0x0(,%rbx,4),%r13d
  lea    -0x1(%rbx),%r15d
  mov    %r13d,%edi
  call   <malloc@plt>
  mov    %r13d,%edx
  mov    %rbp,%rsi
  mov    %rax,%rdi
  mov    %rax,%r12
  call   <memcpy@plt>
  mov    0x0(%rbp),%eax
  mov    %r12,%rsi
  mov    %r13d,%edx
  mov    %rbp,%rdi
  mov    %eax,(%r12)
  call   <memcpy@plt>
  mov    %r12,%rdi
  xor    %r12d,%r12d
  call   <free@plt>
  lea    -0x2(%rbx),%eax
  xor    %r8d,%r8d
  mov    %eax,0x4(%rsp)
  jmp    L121
```

assistant: ```c
void heap(int *values, int n) {
  int i;
  int high_i;
  int low_i;
  int part;
  int value;
  int *dup;
  switch (n) {
  case 0:
  case 1:
    return;
  case 2:
    sort2(&values[0], &values[1]);
    return;
  case 3:
    sort3(&values[0], &values[1], &values[2]);
    return;
  }
  dup = malloc(n * sizeof(int));
  memcpy(dup, values, n * sizeof(int));
  low_i = 0;
  high_i = n - 1;
  part = values[0];
  for (i = 1; i < n; i++) {
    value = values[i];
    if (value < part) {
      dup[low_i] = value;
      low_i++;
    } else {
      dup[high_i] = value;
      high_i--;
    }
  }
  dup[low_i] = part;
  memcpy(values, dup, n * sizeof(int));
  free(dup);
  if (low_i > 1)
    heap(values, low_i);
  if (high_i < (n - 2))
    heap(values + low_i + 1, n - low_i - 1);
}
```