user: Demonstrate the C code that generates the assembly output below:

```asm
<memcpy>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0xb0,%rsp
  mov    %rdi,-0x98(%rbp)
  mov    %rsi,-0xa0(%rbp)
  mov    %rdx,-0xa8(%rbp)
  mov    -0x98(%rbp),%rax
  mov    %rax,-0x88(%rbp)
  mov    -0xa0(%rbp),%rax
  mov    %rax,-0x80(%rbp)
  mov    -0x88(%rbp),%rdx
  mov    -0xa8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x68(%rbp)
  movq   $0x7,-0x60(%rbp)
  mov    -0x88(%rbp),%rdx
  mov    -0x80(%rbp),%rax
  xor    %rdx,%rax
  and    -0x60(%rbp),%rax
  test   %rax,%rax
  jne    L53
  cmpq   $0x7,-0xa8(%rbp)
  ja     L52
L53:
  mov    $0x1,%eax
  jmp    L131
L52:
  mov    $0x0,%eax
L131:
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L30
  nop
  jmp    L143
L45:
  nop
L143:
  mov    -0x88(%rbp),%rax
  cmp    -0x68(%rbp),%rax
  setb   %al
  movzbl %al,%eax
  mov    $0x1,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L39
  jmp    L90
L63:
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x89(%rbp)
  addq   $0x1,-0x88(%rbp)
  addq   $0x1,-0x80(%rbp)
  mov    -0x88(%rbp),%rax
  lea    -0x1(%rax),%rdx
  movzbl -0x89(%rbp),%eax
  mov    %al,(%rdx)
L90:
  mov    -0x88(%rbp),%rax
  cmp    -0x68(%rbp),%rax
  jb     L63
L39:
  mov    -0x98(%rbp),%rax
  jmp    L161
L30:
  mov    -0x88(%rbp),%rax
  and    -0x60(%rbp),%rax
  test   %rax,%rax
  setne  %al
  movzbl %al,%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L72
  jmp    L69
L163:
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x8a(%rbp)
  addq   $0x1,-0x88(%rbp)
  addq   $0x1,-0x80(%rbp)
  mov    -0x88(%rbp),%rax
  lea    -0x1(%rax),%rdx
  movzbl -0x8a(%rbp),%eax
  mov    %al,(%rdx)
L69:
  mov    -0x88(%rbp),%rax
  and    -0x60(%rbp),%rax
  test   %rax,%rax
  jne    L163
L72:
  mov    -0x88(%rbp),%rax
  mov    %rax,-0x78(%rbp)
  mov    -0x80(%rbp),%rax
  mov    %rax,-0x70(%rbp)
  mov    -0x60(%rbp),%rax
  not    %rax
  mov    %rax,%rdx
  mov    -0x68(%rbp),%rax
  and    %rdx,%rax
  mov    %rax,-0x58(%rbp)
  mov    -0x58(%rbp),%rax
  sub    $0x40,%rax
  cmp    %rax,-0x78(%rbp)
  setb   %al
  movzbl %al,%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L64
  jmp    L172
L61:
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x48(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x40(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x38(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x50(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x48(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x40(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x38(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x30(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x28(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x20(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x18(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x10(%rbp),%rdx
  mov    %rdx,(%rax)
L172:
  mov    -0x58(%rbp),%rax
  sub    $0x40,%rax
  cmp    %rax,-0x78(%rbp)
  jb     L61
  jmp    L64
L40:
  mov    -0x70(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,-0x8(%rbp)
  addq   $0x8,-0x78(%rbp)
  addq   $0x8,-0x70(%rbp)
  mov    -0x78(%rbp),%rax
  lea    -0x8(%rax),%rdx
  mov    -0x8(%rbp),%rax
  mov    %rax,(%rdx)
L64:
  mov    -0x78(%rbp),%rax
  cmp    -0x58(%rbp),%rax
  jb     L40
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x88(%rbp)
  mov    -0x70(%rbp),%rax
  mov    %rax,-0x80(%rbp)
  mov    -0x88(%rbp),%rax
  cmp    -0x68(%rbp),%rax
  setb   %al
  movzbl %al,%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  jne    L45
  mov    -0x98(%rbp),%rax
L161:
  leave
  ret
```

assistant: ```c
void *memcpy(void *__restrict aa, const void *__restrict bb, size_t n) {
  char *a = (char *)aa;
  const char *b = (const char *)bb;
  char *end = a + n;
  uintptr_t msk = sizeof(long) - 1;
  if (__builtin_expect(!!((((uintptr_t)a & msk) != ((uintptr_t)b & msk)) || n < sizeof(long)), 0)) {
  small:
    if (__builtin_expect(a < end, 1))
      while (a < end) {
        char tt = *b;
        a++, b++;
        *(a - 1) = tt;
      };
    return aa;
  }
  if (__builtin_expect(!!(((uintptr_t)a & msk) != 0), 0))
    while ((uintptr_t)a & msk) {
      char tt = *b;
      a++, b++;
      *(a - 1) = tt;
    };
  long *la = (long *)a;
  const long *lb = (const long *)b;
  long *lend = (long *)((uintptr_t)end & ~msk);
  if (__builtin_expect(!!(la < (lend - 8)), 0)) {
    while (la < (lend - 8)) {
      long b0 = *lb++;
      long b1 = *lb++;
      long b2 = *lb++;
      long b3 = *lb++;
      long b4 = *lb++;
      long b5 = *lb++;
      long b6 = *lb++;
      long b7 = *lb++;
      long b8 = *lb++;
      *la++ = b0;
      *la++ = b1;
      *la++ = b2;
      *la++ = b3;
      *la++ = b4;
      *la++ = b5;
      *la++ = b6;
      *la++ = b7;
      *la++ = b8;
    }
  }
  while (la < lend) {
    long tt = *lb;
    la++, lb++;
    *(la - 1) = tt;
  };
  a = (char *)la;
  b = (const char *)lb;
  if (__builtin_expect(!!(a < end), 0))
    goto small;
  return aa;
}
```