user: What would the C source look like for the assembly code provided here:

```asm
<memmove>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x30(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L0
  mov    -0x18(%rbp),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  cmp    %rax,-0x20(%rbp)
  jae    L0
  mov    -0x38(%rbp),%rax
  add    %rax,-0x18(%rbp)
  mov    -0x38(%rbp),%rax
  add    %rax,-0x20(%rbp)
  jmp    L125
L33:
  subq   $0x1,-0x18(%rbp)
  subq   $0x1,-0x20(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%edx
  mov    -0x20(%rbp),%rax
  mov    %dl,(%rax)
L125:
  mov    -0x38(%rbp),%rax
  lea    -0x1(%rax),%rdx
  mov    %rdx,-0x38(%rbp)
  test   %rax,%rax
  jne    L33
  jmp    L109
L0:
  cmpq   $0x1f,-0x38(%rbp)
  jbe    L65
  mov    -0x18(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  or     %rdx,%rax
  and    $0x7,%eax
  test   %rax,%rax
  jne    L65
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  jmp    L118
L94:
  mov    -0x8(%rbp),%rdx
  lea    0x8(%rdx),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x8(%rax),%rcx
  mov    %rcx,-0x10(%rbp)
  mov    (%rdx),%rdx
  mov    %rdx,(%rax)
  mov    -0x8(%rbp),%rdx
  lea    0x8(%rdx),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x8(%rax),%rcx
  mov    %rcx,-0x10(%rbp)
  mov    (%rdx),%rdx
  mov    %rdx,(%rax)
  mov    -0x8(%rbp),%rdx
  lea    0x8(%rdx),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x8(%rax),%rcx
  mov    %rcx,-0x10(%rbp)
  mov    (%rdx),%rdx
  mov    %rdx,(%rax)
  mov    -0x8(%rbp),%rdx
  lea    0x8(%rdx),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x8(%rax),%rcx
  mov    %rcx,-0x10(%rbp)
  mov    (%rdx),%rdx
  mov    %rdx,(%rax)
  subq   $0x20,-0x38(%rbp)
L118:
  cmpq   $0x1f,-0x38(%rbp)
  ja     L94
  jmp    L114
L56:
  mov    -0x8(%rbp),%rdx
  lea    0x8(%rdx),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x8(%rax),%rcx
  mov    %rcx,-0x10(%rbp)
  mov    (%rdx),%rdx
  mov    %rdx,(%rax)
  subq   $0x8,-0x38(%rbp)
L114:
  cmpq   $0x7,-0x38(%rbp)
  ja     L56
  mov    -0x10(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x8(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  jmp    L65
L50:
  mov    -0x18(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x20(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x20(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
L65:
  mov    -0x38(%rbp),%rax
  lea    -0x1(%rax),%rdx
  mov    %rdx,-0x38(%rbp)
  test   %rax,%rax
  jne    L50
L109:
  mov    -0x28(%rbp),%rax
  pop    %rbp
  ret
```

assistant: ```c
void *memmove(void *dst_void, const void *src_void, size_t length) {
  char *dst = dst_void;
  const char *src = src_void;
  long *aligned_dst;
  const long *aligned_src;
  if (src < dst && dst < src + length) {
    src += length;
    dst += length;
    while (length--)
      *--dst = *--src;
  } else {
    if (!((length) < (sizeof(long) << 2)) && !(((long)src & (sizeof(long) - 1)) | ((long)dst & (sizeof(long) - 1)))) {
      aligned_dst = (long *)dst;
      aligned_src = (long *)src;
      while (length >= (sizeof(long) << 2)) {
        *aligned_dst++ = *aligned_src++;
        *aligned_dst++ = *aligned_src++;
        *aligned_dst++ = *aligned_src++;
        *aligned_dst++ = *aligned_src++;
        length -= (sizeof(long) << 2);
      }
      while (length >= (sizeof(long))) {
        *aligned_dst++ = *aligned_src++;
        length -= (sizeof(long));
      }
      dst = (char *)aligned_dst;
      src = (char *)aligned_src;
    }
    while (length--)
      *dst++ = *src++;
  }
  return dst_void;
}
```