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

```asm
<my_strchrnul>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x20,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %esi,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  movzbl %al,%eax
  mov    %eax,-0x1c(%rbp)
  cmpl   $0x0,-0x1c(%rbp)
  jne    L61
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <my_strlen@plt>
  movslq %eax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  jmp    L94
L110:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L57
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  cmp    %eax,-0x1c(%rbp)
  jne    L14
L57:
  mov    -0x18(%rbp),%rax
  jmp    L94
L14:
  addq   $0x1,-0x18(%rbp)
L61:
  mov    -0x18(%rbp),%rax
  and    $0x7,%eax
  test   %rax,%rax
  jne    L110
  mov    D48(%rip),%rax
  mov    (%rax),%rsi
  mov    $0xffffffffffffffff,%rax
  mov    $0x0,%edx
  div    %rsi
  mov    %rax,%rdx
  mov    -0x1c(%rbp),%eax
  cltq
  imul   %rdx,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  jmp    L117
L17:
  addq   $0x8,-0x10(%rbp)
L117:
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rcx
  mov    D48(%rip),%rax
  mov    (%rax),%rdi
  mov    $0xffffffffffffffff,%rax
  mov    $0x0,%edx
  div    %rdi
  sub    %rax,%rcx
  mov    %rcx,%rdx
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  not    %rax
  mov    %rdx,%rcx
  and    %rax,%rcx
  mov    D48(%rip),%rax
  mov    (%rax),%rsi
  mov    $0xffffffffffffffff,%rax
  mov    $0x0,%edx
  div    %rsi
  mov    %rax,%rdx
  mov    D48(%rip),%rax
  mov    (%rax),%rax
  shr    %rax
  add    $0x1,%rax
  imul   %rdx,%rax
  and    %rcx,%rax
  test   %rax,%rax
  jne    L0
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  xor    -0x8(%rbp),%rax
  mov    %rax,%rcx
  mov    D48(%rip),%rax
  mov    (%rax),%rdi
  mov    $0xffffffffffffffff,%rax
  mov    $0x0,%edx
  div    %rdi
  sub    %rax,%rcx
  mov    %rcx,%rdx
  mov    -0x10(%rbp),%rax
  mov    (%rax),%rax
  xor    -0x8(%rbp),%rax
  not    %rax
  and    %rax,%rdx
  mov    %rdx,%rcx
  mov    D48(%rip),%rax
  mov    (%rax),%rsi
  mov    $0xffffffffffffffff,%rax
  mov    $0x0,%edx
  div    %rsi
  mov    %rax,%rdx
  mov    D48(%rip),%rax
  mov    (%rax),%rax
  shr    %rax
  add    $0x1,%rax
  imul   %rdx,%rax
  and    %rcx,%rax
  test   %rax,%rax
  je     L17
L0:
  mov    -0x10(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  jmp    L15
L21:
  addq   $0x1,-0x18(%rbp)
L15:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L1
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  cmp    %eax,-0x1c(%rbp)
  jne    L21
L1:
  mov    -0x18(%rbp),%rax
L94:
  leave
  ret
```

assistant: ```c
char *my_strchrnul(const char *s, int c) {
  size_t *w, k;
  c = (unsigned char)c;
  if (!c)
    return (char *)s + my_strlen(s);
  for (; (uintptr_t)s % (sizeof(size_t)); s++)
    if (!*s || *(unsigned char *)s == c)
      return (char *)s;
  k = ((size_t)-1 / UCHAR_MAX) * c;
  for (w = (void *)s; !((*w) - ((size_t)-1 / UCHAR_MAX) & ~(*w) & (((size_t)-1 / UCHAR_MAX) * (UCHAR_MAX / 2 + 1))) && !((*w ^ k) - ((size_t)-1 / UCHAR_MAX) & ~(*w ^ k) & (((size_t)-1 / UCHAR_MAX) * (UCHAR_MAX / 2 + 1))); w++)
    ;
  for (s = (void *)w; *s && *(unsigned char *)s != c; s++)
    ;
  return (char *)s;
}
```