user: Translate the below assembly code into C programming language:

```asm
<strrep>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %rdx,0x20(%rsp)
  test   %rsi,%rsi
  sete   %al
  test   %rdx,%rdx
  sete   %dl
  or     %dl,%al
  jne    L91
  mov    %rdi,%rbp
  mov    %rsi,%rbx
  test   %rdi,%rdi
  je     L91
  call   <strlen@plt>
  mov    %rax,0x30(%rsp)
  test   %rax,%rax
  je     L8
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %rax,0x8(%rsp)
  test   %rax,%rax
  je     L8
  mov    %rbp,%rdi
  mov    $0x0,%r12d
  jmp    L140
L67:
  mov    0x8(%rsp),%rax
  lea    0x0(%r13,%rax,1),%rdi
  add    $0x1,%r12
L140:
  mov    %rbx,%rsi
  call   <strstr@plt>
  mov    %rax,%r13
  test   %rax,%rax
  jne    L67
  test   %r12,%r12
  je     L8
  mov    0x8(%rsp),%rax
  imul   %r12,%rax
  mov    0x30(%rsp),%r14
  sub    %rax,%r14
  mov    0x20(%rsp),%rdi
  call   <strlen@plt>
  mov    %rax,0x28(%rsp)
  mov    %rax,%rdi
  imul   %r12,%rdi
  add    %r14,%rdi
  test   %rax,%rax
  je     L146
  cmp    %rdi,%r14
  jae    L33
  cmp    $0xffffffffffffffff,%rdi
  je     L33
L146:
  add    $0x1,%rdi
  call   <malloc@plt>
  mov    %rax,0x38(%rsp)
  mov    %rax,%r14
  test   %rax,%rax
  je     L14
  mov    %rbp,%r13
  mov    $0x0,%r15d
L52:
  mov    %rbx,%rsi
  mov    %r13,%rdi
  call   <strstr@plt>
  mov    %rax,0x10(%rsp)
  sub    %r13,%rax
  mov    %rax,0x18(%rsp)
  mov    %rax,%rdx
  mov    %r13,%rsi
  mov    %r14,%rdi
  call   <memcpy@plt>
  add    0x18(%rsp),%r14
  mov    0x28(%rsp),%r13
  mov    %r13,%rdx
  mov    0x20(%rsp),%rsi
  mov    %r14,%rdi
  call   <memcpy@plt>
  add    %r13,%r14
  mov    0x10(%rsp),%r13
  add    0x8(%rsp),%r13
  add    $0x1,%r15
  cmp    %r15,%r12
  jne    L52
  sub    %r13,%rbp
  mov    0x30(%rsp),%rax
  lea    0x1(%rbp,%rax,1),%rdx
  mov    %r13,%rsi
  mov    %r14,%rdi
  call   <memcpy@plt>
  mov    0x38(%rsp),%rbp
  jmp    L8
L91:
  mov    $0x0,%ebp
L8:
  mov    %rbp,%rax
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L33:
  mov    %r13,%rbp
  jmp    L8
L14:
  mov    %r13,%rbp
  jmp    L8
```

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;
}
```