user: What is the c source code of the assembly code below?

```asm
<strrep>:
  endbr64
  push   %r15
  push   %r14
  mov    %rdx,%r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  test   %rsi,%rsi
  sete   %al
  test   %rdx,%rdx
  sete   %dl
  or     %dl,%al
  jne    L124
  mov    %rdi,%r12
  test   %rdi,%rdi
  je     L124
  mov    %rsi,%rbx
  call   <strlen@plt>
  mov    %rax,0x20(%rsp)
  test   %rax,%rax
  je     L57
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %rax,%r13
  test   %rax,%rax
  je     L57
  mov    %r12,%rdi
  mov    %rbx,%rsi
  xor    %ebp,%ebp
  call   <strstr@plt>
  test   %rax,%rax
  je     L63
  nopl   0x0(%rax)
L7:
  lea    (%rax,%r13,1),%rdi
  mov    %rbx,%rsi
  add    $0x1,%rbp
  call   <strstr@plt>
  test   %rax,%rax
  jne    L7
L63:
  test   %rbp,%rbp
  je     L57
  mov    %rbp,%rax
  mov    0x20(%rsp),%r15
  mov    %r14,%rdi
  imul   %r13,%rax
  sub    %rax,%r15
  call   <strlen@plt>
  mov    %rax,%rdi
  mov    %rax,(%rsp)
  imul   %rbp,%rdi
  add    %r15,%rdi
  test   %rax,%rax
  je     L101
  cmp    %rdi,%r15
  jae    L124
  cmp    $0xffffffffffffffff,%rdi
  je     L124
L101:
  add    $0x1,%rdi
  call   <malloc@plt>
  mov    %rax,0x28(%rsp)
  mov    %rax,%r15
  test   %rax,%rax
  je     L124
  mov    %r12,%r9
  xor    %r8d,%r8d
  nopl   0x0(%rax,%rax,1)
L98:
  mov    %r9,%rdi
  mov    %rbx,%rsi
  mov    %r8,0x18(%rsp)
  mov    %r9,0x8(%rsp)
  call   <strstr@plt>
  mov    0x8(%rsp),%r9
  mov    %r15,%rdi
  mov    %rax,%rdx
  mov    %rax,0x10(%rsp)
  sub    %r9,%rdx
  mov    %r9,%rsi
  mov    %rdx,0x8(%rsp)
  call   <memcpy@plt>
  mov    0x8(%rsp),%rdx
  mov    %r14,%rsi
  add    %rdx,%r15
  mov    (%rsp),%rdx
  mov    %r15,%rdi
  call   <memcpy@plt>
  mov    0x18(%rsp),%r8
  mov    0x10(%rsp),%rcx
  add    (%rsp),%r15
  add    $0x1,%r8
  lea    (%rcx,%r13,1),%r9
  cmp    %r8,%rbp
  jne    L98
  mov    0x20(%rsp),%rax
  sub    %r9,%r12
  mov    %r9,%rsi
  mov    %r15,%rdi
  lea    0x1(%r12,%rax,1),%rdx
  call   <memcpy@plt>
  mov    0x28(%rsp),%r12
L57:
  add    $0x38,%rsp
  mov    %r12,%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  xchg   %ax,%ax
L124:
  xor    %r12d,%r12d
  jmp    L57
```

assistant: ```c
char *strrep(const char *s1, const char *s2, const char *s3) {
  if (!s1 || !s2 || !s3)
    return 0;
  size_t s1_len = strlen(s1);
  if (!s1_len)
    return (char *)s1;
  size_t s2_len = strlen(s2);
  if (!s2_len)
    return (char *)s1;
  size_t count = 0;
  const char *p = s1;
  do {
    p = strstr(p, s2);
    if (p) {
      p += s2_len;
      ++count;
    }
  } while (p);
  if (!count)
    return (char *)s1;
  size_t s1_without_s2_len = s1_len - count * s2_len;
  size_t s3_len = strlen(s3);
  size_t newstr_len = s1_without_s2_len + count * s3_len;
  if (s3_len && ((newstr_len <= s1_without_s2_len) || (newstr_len + 1 == 0)))
    return 0;
  char *newstr = (char *)malloc(newstr_len + 1);
  if (!newstr)
    return 0;
  char *dst = newstr;
  const char *start_substr = s1;
  size_t i;
  for (i = 0; i != count; ++i) {
    const char *end_substr = strstr(start_substr, s2);
    size_t substr_len = end_substr - start_substr;
    memcpy(dst, start_substr, substr_len);
    dst += substr_len;
    memcpy(dst, s3, s3_len);
    dst += s3_len;
    start_substr = end_substr + s2_len;
  }
  size_t remains = s1_len - (start_substr - s1) + 1;
  memcpy(dst, start_substr, remains);
  return newstr;
}
```