user: 下面的汇编指令对应的C源代码是什么：

```asm
<simple_memmem>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %rdi,%rbp
  push   %rbx
  sub    $0x18,%rsp
  test   %rcx,%rcx
  je     L87
  mov    %rsi,%r12
  mov    %rdx,%r15
  movzbl (%rdx),%esi
  mov    %rcx,%r13
  mov    %r12,%rdx
  cmp    $0x1,%rcx
  jne    L128
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1060 <memchr@plt>
  nopw   0x0(%rax,%rax,1)
L87:
  mov    %rdi,%r14
L59:
  add    $0x18,%rsp
  mov    %r14,%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   (%rax)
L128:
  call   <memchr@plt>
  mov    %rax,%r14
  test   %rax,%rax
  je     L139
  sub    %rbp,%rax
  mov    %r12,%rcx
  sub    %rax,%rcx
  cmp    %rcx,%r13
  ja     L139
  lea    0x1(%r15),%r8
  lea    (%r15,%r13,1),%rax
  lea    0x1(%r14),%r12
  cmp    %rax,%r8
  je     L53
  mov    $0x1,%eax
  xor    %ebx,%ebx
  nop
L148:
  movzbl (%r14,%rax,1),%edx
  movzbl (%r15,%rax,1),%esi
  add    $0x1,%rax
  add    %ebx,%edx
  sub    %esi,%edx
  mov    %edx,%ebx
  cmp    %rax,%r13
  jne    L148
  lea    (%r14,%r13,1),%rbp
  test   %edx,%edx
  je     L147
L35:
  add    %r14,%rcx
  cmp    %rbp,%rcx
  je     L139
  sub    $0x1,%r13
  jmp    L47
  nop
L78:
  cmp    %rbp,%rcx
  je     L139
L70:
  add    $0x1,%r12
L47:
  movzbl -0x1(%r12),%eax
  add    $0x1,%rbp
  mov    %r12,%r14
  sub    %eax,%ebx
  movzbl -0x1(%rbp),%eax
  add    %eax,%ebx
  jne    L78
  mov    %r13,%rdx
  mov    %r15,%rsi
  mov    %r12,%rdi
  mov    %rcx,0x8(%rsp)
  call   <memcmp@plt>
  mov    0x8(%rsp),%rcx
  test   %rax,%rax
  je     L59
  cmp    %rbp,%rcx
  jne    L70
L139:
  xor    %r14d,%r14d
  jmp    L59
L53:
  mov    %r12,%rbp
L147:
  lea    -0x2(%r13),%rdx
  mov    %r8,%rsi
  mov    %r12,%rdi
  mov    %rcx,0x8(%rsp)
  call   <memcmp@plt>
  test   %rax,%rax
  je     L59
  mov    0x8(%rsp),%rcx
  xor    %ebx,%ebx
  jmp    L35
```

assistant: ```c
char *simple_memmem(const char *haystack, size_t haystacklen, const char *needle, size_t needlelen) {
  const char *needle_ptr;
  const char *haystack_ptr;
  int sums_diff;
  switch (needlelen) {
  case (0):
    return (char *)haystack;
    break;
  case (1):
    return memchr(haystack, *((unsigned char *)needle), haystacklen);
    break;
  }
  haystack_ptr = memchr(haystack, *((unsigned char *)needle), haystacklen);
  if (!haystack_ptr) {
    return NULL;
  }
  haystacklen -= (haystack_ptr - haystack);
  if (haystacklen < needlelen) {
    return NULL;
  }
  haystack = haystack_ptr;
  sums_diff = 0;
  needle_ptr = needle + 1;
  haystack_ptr++;
  needle += needlelen;
  while (needle_ptr != needle) {
    sums_diff += *((unsigned char *)haystack_ptr++);
    sums_diff -= *((unsigned char *)needle_ptr++);
  }
  needle -= needlelen;
  if (sums_diff == 0 && memcmp(haystack + 1, needle + 1, needlelen - 2) == 0) {
    return (char *)haystack;
  }
  needle_ptr = haystack + haystacklen;
  while (haystack_ptr != needle_ptr) {
    sums_diff -= *((unsigned char *)haystack++);
    sums_diff += *((unsigned char *)haystack_ptr++);
    if (sums_diff == 0 && memcmp(haystack, needle, needlelen - 1) == 0) {
      return (char *)haystack;
    }
  }
  return NULL;
}
```