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

```asm
<string_strcmp_ignore_chars>:
  endbr64
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  mov    %rsi,%rbp
  test   %rdi,%rdi
  je     L14
  mov    %rdx,%r12
  mov    %ecx,%r13d
  test   %rsi,%rsi
  je     L14
  cmpb   $0x0,(%rdi)
  jne    L664
  jmp    L183
L14:
  mov    $0x1,%r14d
  test   %rbx,%rbx
  je     L540
L538:
  mov    %r14d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
L540:
  neg    %rbp
  sbb    %r14d,%r14d
  jmp    L538
L491:
  mov    %rbp,%rsi
  mov    %rbx,%rdi
  call   <utf8_charcasecmp@plt>
  mov    %eax,%r14d
  jmp    L620
L423:
  sar    $0x1f,%r14d
  or     $0x1,%r14d
  jmp    L538
L358:
  test   %rbx,%rbx
  je     L136
  cmpb   $0x0,(%rbx)
  je     L579
  test   %rbp,%rbp
  je     L579
L664:
  cmpb   $0x0,0x0(%rbp)
  je     L99
  test   %rbx,%rbx
  je     L320
L608:
  movzbl (%rbx),%esi
  test   %sil,%sil
  je     L320
  movsbl %sil,%esi
  mov    %r12,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L320
  mov    %rbx,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbx
  test   %rax,%rax
  jne    L608
L320:
  movzbl 0x0(%rbp),%esi
  test   %sil,%sil
  je     L16
  movsbl %sil,%esi
  mov    %r12,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L162
  mov    %rbp,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  jne    L320
  test   %rbx,%rbx
  je     L512
  cmpb   $0x0,(%rbx)
  je     L496
L463:
  test   %rbp,%rbp
  je     L354
L477:
  cmpb   $0x0,0x0(%rbp)
  je     L121
L577:
  test   %r13d,%r13d
  je     L491
  movsbl (%rbx),%r14d
  movsbl 0x0(%rbp),%eax
  sub    %eax,%r14d
L620:
  test   %r14d,%r14d
  jne    L423
  mov    %rbx,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbx
  mov    %rbp,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbp
  test   %rbx,%rbx
  je     L687
L4:
  movzbl (%rbx),%esi
  test   %sil,%sil
  je     L647
  movsbl %sil,%esi
  mov    %r12,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L687
  mov    %rbx,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbx
  test   %rax,%rax
  jne    L4
L687:
  test   %rbp,%rbp
  je     L275
L339:
  movzbl 0x0(%rbp),%esi
  test   %sil,%sil
  je     L358
  movsbl %sil,%esi
  mov    %r12,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L358
  mov    %rbp,%rdi
  call   <utf8_next_char@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  jne    L339
L275:
  test   %rbx,%rbx
  jne    L286
L11:
  test   %rbx,%rbx
  je     L538
  mov    %rbx,%rbp
  mov    $0x0,%ebx
  jmp    L183
L99:
  test   %rbx,%rbx
  jne    L579
  jmp    L183
L116:
  mov    $0x0,%r14d
  jmp    L538
L225:
  mov    $0x0,%r14d
  jmp    L538
L318:
  mov    $0xffffffff,%r14d
  jmp    L538
L121:
  mov    $0x1,%r14d
  jmp    L538
L512:
  mov    $0x0,%r14d
  jmp    L538
L18:
  mov    $0x1,%r14d
  jmp    L538
L354:
  mov    $0x1,%r14d
  jmp    L538
L496:
  mov    $0x0,%r14d
  jmp    L538
L357:
  mov    $0x0,%r14d
  jmp    L538
L29:
  mov    $0x0,%r14d
  test   %rbp,%rbp
  je     L538
L183:
  mov    $0xffffffff,%r14d
  cmpb   $0x0,0x0(%rbp)
  jne    L538
  mov    $0x0,%r14d
  test   %rbx,%rbx
  je     L538
  cmpb   $0x0,(%rbx)
  jne    L648
  mov    $0x0,%r14d
  jmp    L538
L136:
  mov    %rbp,%rbx
  jmp    L11
L286:
  mov    $0x0,%ebp
L579:
  cmpb   $0x0,(%rbx)
  je     L29
  test   %rbp,%rbp
  je     L18
L648:
  cmpb   $0x0,0x0(%rbp)
  sete   %r14b
  movzbl %r14b,%r14d
  jmp    L538
L647:
  test   %rbp,%rbp
  jne    L339
  jmp    L579
L162:
  test   %rbx,%rbx
  je     L616
  jmp    L689
L16:
  test   %rbx,%rbx
  je     L357
L689:
  cmpb   $0x0,(%rbx)
  jne    L463
  test   %rbp,%rbp
  je     L116
L616:
  cmpb   $0x0,0x0(%rbp)
  je     L225
  test   %rbx,%rbx
  je     L602
  cmpb   $0x0,(%rbx)
  jne    L463
  test   %rbp,%rbp
  je     L577
L602:
  cmpb   $0x0,0x0(%rbp)
  jne    L318
  test   %rbx,%rbx
  je     L577
  cmpb   $0x0,(%rbx)
  je     L577
  jmp    L477
```

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