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

```asm
<strrep>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x90,%rsp
  mov    %rdi,-0x78(%rbp)
  mov    %rsi,-0x80(%rbp)
  mov    %rdx,-0x88(%rbp)
  cmpq   $0x0,-0x78(%rbp)
  je     L166
  cmpq   $0x0,-0x80(%rbp)
  je     L166
  cmpq   $0x0,-0x88(%rbp)
  jne    L69
L166:
  mov    $0x0,%eax
  jmp    L165
L69:
  mov    -0x78(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %rax,-0x48(%rbp)
  cmpq   $0x0,-0x48(%rbp)
  jne    L115
  mov    -0x78(%rbp),%rax
  jmp    L165
L115:
  mov    -0x80(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %rax,-0x40(%rbp)
  cmpq   $0x0,-0x40(%rbp)
  jne    L68
  mov    -0x78(%rbp),%rax
  jmp    L165
L68:
  movq   $0x0,-0x70(%rbp)
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x68(%rbp)
L163:
  mov    -0x80(%rbp),%rdx
  mov    -0x68(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strstr@plt>
  mov    %rax,-0x68(%rbp)
  cmpq   $0x0,-0x68(%rbp)
  je     L147
  mov    -0x40(%rbp),%rax
  add    %rax,-0x68(%rbp)
  addq   $0x1,-0x70(%rbp)
L147:
  cmpq   $0x0,-0x68(%rbp)
  jne    L163
  cmpq   $0x0,-0x70(%rbp)
  jne    L37
  mov    -0x78(%rbp),%rax
  jmp    L165
L37:
  mov    -0x70(%rbp),%rax
  imul   -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x48(%rbp),%rax
  sub    %rdx,%rax
  mov    %rax,-0x38(%rbp)
  mov    -0x88(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %rax,-0x30(%rbp)
  mov    -0x70(%rbp),%rax
  imul   -0x30(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x28(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  je     L3
  mov    -0x28(%rbp),%rax
  cmp    -0x38(%rbp),%rax
  jbe    L164
  cmpq   $0xffffffffffffffff,-0x28(%rbp)
  jne    L3
L164:
  mov    $0x0,%eax
  jmp    L165
L3:
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,%rdi
  call   <malloc@plt>
  mov    %rax,-0x20(%rbp)
  cmpq   $0x0,-0x20(%rbp)
  jne    L35
  mov    $0x0,%eax
  jmp    L165
L35:
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x60(%rbp)
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x58(%rbp)
  movq   $0x0,-0x50(%rbp)
  jmp    L23
L99:
  mov    -0x80(%rbp),%rdx
  mov    -0x58(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strstr@plt>
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rax
  sub    -0x58(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x58(%rbp),%rcx
  mov    -0x60(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x8(%rbp),%rax
  add    %rax,-0x60(%rbp)
  mov    -0x30(%rbp),%rdx
  mov    -0x88(%rbp),%rcx
  mov    -0x60(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x30(%rbp),%rax
  add    %rax,-0x60(%rbp)
  mov    -0x10(%rbp),%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x58(%rbp)
  addq   $0x1,-0x50(%rbp)
L23:
  mov    -0x50(%rbp),%rax
  cmp    -0x70(%rbp),%rax
  jne    L99
  mov    -0x58(%rbp),%rax
  sub    -0x78(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x48(%rbp),%rax
  sub    %rdx,%rax
  add    $0x1,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rdx
  mov    -0x58(%rbp),%rcx
  mov    -0x60(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x20(%rbp),%rax
L165:
  leave
  ret
```

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