user: Please show me the C implementation that matches the assembly code listed below:

```asm
<string_strcmp_ignore_chars>:
  endbr64
  push   %r13
  push   %r12
  mov    %rsi,%r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  test   %rdi,%rdi
  je     L93
  mov    %rdi,%rbp
  mov    %rdx,%rbx
  mov    %ecx,%r13d
  test   %rsi,%rsi
  je     L316
  nopl   0x0(%rax)
L10:
  movsbl 0x0(%rbp),%esi
  test   %sil,%sil
  je     L164
  test   %r12,%r12
  je     L341
  cmpb   $0x0,(%r12)
  jne    L317
  jmp    L341
  nopl   0x0(%rax,%rax,1)
L173:
  movsbl (%rax),%esi
  test   %sil,%sil
  je     L365
L317:
  mov    %rbx,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L365
  mov    %rbp,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  jne    L173
  nopl   (%rax)
L365:
  movsbl (%r12),%esi
  test   %sil,%sil
  je     L350
  mov    %rbx,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L350
  mov    %r12,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%r12
  test   %rax,%rax
  jne    L365
L299:
  test   %rbp,%rbp
  je     L359
  cmpb   $0x0,0x0(%rbp)
  je     L359
L341:
  mov    $0x1,%eax
L92:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
  nopw   0x0(%rax,%rax,1)
L350:
  test   %rbp,%rbp
  je     L300
  cmpb   $0x0,0x0(%rbp)
  je     L300
  movsbl (%r12),%edx
  test   %dl,%dl
  je     L341
  test   %r13d,%r13d
  je     L269
  movsbl 0x0(%rbp),%eax
  sub    %edx,%eax
L94:
  test   %eax,%eax
  jne    L82
  mov    %rbp,%rdi
  call   <utf8_next_char@plt>
  mov    %r12,%rdi
  mov    %rax,%rbp
  call   <utf8_next_char@plt>
  mov    %rax,%r12
  test   %rbp,%rbp
  jne    L366
  jmp    L310
  nopl   0x0(%rax,%rax,1)
L261:
  mov    %rbx,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L193
  mov    %rbp,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  je     L193
L366:
  movsbl 0x0(%rbp),%esi
  test   %sil,%sil
  jne    L261
L193:
  test   %r12,%r12
  jne    L329
  jmp    L299
L220:
  mov    %rbx,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L260
  mov    %r12,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L260
L329:
  movsbl (%r12),%esi
  test   %sil,%sil
  jne    L220
L260:
  test   %rbp,%rbp
  jne    L10
L164:
  test   %r12,%r12
  je     L359
  cmpb   $0x0,(%r12)
  jne    L78
  nopl   0x0(%rax)
L359:
  xor    %eax,%eax
L318:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
  nopl   (%rax)
L300:
  cmpb   $0x0,(%r12)
  je     L359
L78:
  add    $0x8,%rsp
  mov    $0xffffffff,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
  nopw   0x0(%rax,%rax,1)
L269:
  mov    %r12,%rsi
  mov    %rbp,%rdi
  call   <utf8_charcasecmp@plt>
  jmp    L94
L316:
  test   %rdi,%rdi
  jne    L341
L93:
  neg    %r12
  sbb    %eax,%eax
  jmp    L92
L310:
  test   %rax,%rax
  jne    L329
  xor    %eax,%eax
  jmp    L318
  nopl   0x0(%rax)
L82:
  jns    L341
  jmp    L78
```

assistant: ```c
int string_strcmp_ignore_chars(const char *string1, const char *string2, const char *chars_ignored, int case_sensitive) {
  int diff;
  if (!string1 || !string2)
    return (string1) ? 1 : ((string2) ? -1 : 0);
  while (string1 && string1[0] && string2 && string2[0]) {
    while (string1 && string1[0] && strchr(chars_ignored, string1[0])) {
      string1 = utf8_next_char(string1);
    }
    while (string2 && string2[0] && strchr(chars_ignored, string2[0])) {
      string2 = utf8_next_char(string2);
    }
    if ((!string1 || !string1[0]) && (!string2 || !string2[0]))
      return 0;
    if ((!string1 || !string1[0]) && string2 && string2[0])
      return -1;
    if (string1 && string1[0] && (!string2 || !string2[0]))
      return 1;
    diff = (case_sensitive) ? (int)string1[0] - (int)string2[0] : utf8_charcasecmp(string1, string2);
    if (diff != 0)
      return (diff < 0) ? -1 : 1;
    string1 = utf8_next_char(string1);
    string2 = utf8_next_char(string2);
    while (string1 && string1[0] && strchr(chars_ignored, string1[0])) {
      string1 = utf8_next_char(string1);
    }
    while (string2 && string2[0] && strchr(chars_ignored, string2[0])) {
      string2 = utf8_next_char(string2);
    }
  }
  if ((!string1 || !string1[0]) && string2 && string2[0])
    return -1;
  if (string1 && string1[0] && (!string2 || !string2[0]))
    return 1;
  return 0;
}
```