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

```asm
<bsearch_range>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x70,%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    -0x68(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  movq   $0x0,-0x38(%rbp)
  mov    -0x70(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  jmp    L27
L114:
  mov    -0x38(%rbp),%rdx
  mov    -0x30(%rbp),%rax
  add    %rdx,%rax
  shr    %rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  imul   0x10(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x48(%rbp),%rax
  mov    0x18(%rbp),%rdx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   *%rdx
  mov    %eax,-0x3c(%rbp)
  cmpl   $0x0,-0x3c(%rbp)
  jg     L1
  mov    -0x8(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  jmp    L27
L1:
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x38(%rbp)
L27:
  mov    -0x38(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jb     L114
  mov    -0x38(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  jae    L91
  mov    -0x38(%rbp),%rax
  imul   0x10(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rax,%rdx
  mov    -0x58(%rbp),%rax
  mov    %rdx,(%rax)
  jmp    L153
L91:
  mov    -0x58(%rbp),%rax
  movq   $0x0,(%rax)
L153:
  mov    -0x50(%rbp),%rdx
  mov    -0x48(%rbp),%rax
  mov    0x18(%rbp),%rcx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   *%rcx
  test   %eax,%eax
  jle    L36
  mov    -0x60(%rbp),%rax
  movq   $0x0,(%rax)
  jmp    L105
L36:
  mov    -0x30(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x70(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  jmp    L23
L99:
  mov    -0x28(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  shr    %rax
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rax
  imul   0x10(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x50(%rbp),%rax
  mov    0x18(%rbp),%rdx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   *%rdx
  mov    %eax,-0x40(%rbp)
  cmpl   $0x0,-0x40(%rbp)
  jns    L42
  mov    -0x10(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  jmp    L23
L42:
  mov    -0x10(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x28(%rbp)
L23:
  mov    -0x28(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L155
  mov    -0x28(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  jb     L99
L155:
  mov    -0x28(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  je     L15
  mov    -0x28(%rbp),%rax
  imul   0x10(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x50(%rbp),%rax
  mov    0x18(%rbp),%rdx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   *%rdx
  test   %eax,%eax
  jns    L147
L15:
  mov    -0x28(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jbe    L8
  mov    -0x28(%rbp),%rax
  sub    $0x1,%rax
  imul   0x10(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rax,%rdx
  mov    -0x60(%rbp),%rax
  mov    %rdx,(%rax)
  jmp    L105
L8:
  mov    -0x60(%rbp),%rax
  movq   $0x0,(%rax)
  jmp    L105
L147:
  mov    -0x28(%rbp),%rax
  imul   0x10(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rax,%rdx
  mov    -0x60(%rbp),%rax
  mov    %rdx,(%rax)
L105:
  leave
  ret
```

assistant: ```c
void bsearch_range(const void *key1, const void *key2, void *p1, void *p2, const void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *)) {
  const char *b = (const char *)base;
  size_t l1, u1, l2, u2;
  l1 = 0;
  u1 = nmemb;
  while (l1 < u1) {
    size_t idx = (l1 + u1) / 2;
    int comp = (*cmp)(key1, b + idx * size);
    if (comp <= 0)
      u1 = idx;
    else
      l1 = idx + 1;
  }
  if (l1 < nmemb)
    *(const void **)p1 = b + l1 * size;
  else
    *(const void **)p1 = NULL;
  if (((*cmp)(key1, key2)) > 0) {
    *(const void **)p2 = NULL;
    return;
  }
  l2 = u1;
  u2 = nmemb;
  while (l2 < u2 && l2 < nmemb) {
    size_t idx = (l2 + u2) / 2;
    int comp = (*cmp)(key2, b + idx * size);
    if (comp < 0)
      u2 = idx;
    else
      l2 = idx + 1;
  }
  if (l2 == nmemb || ((*cmp)(key2, b + l2 * size)) < 0) {
    if (l2 > u1)
      *(const void **)p2 = b + (l2 - 1) * size;
    else
      *(const void **)p2 = NULL;
  } else
    *(const void **)p2 = b + l2 * size;
}
```