user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<fnmatch>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %edx,-0x54(%rbp)
  mov    -0x48(%rbp),%r12
  mov    -0x50(%rbp),%rbx
  jmp    L1152
L386:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L1287
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1287
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L915
L1287:
  mov    %r13d,%eax
L915:
  mov    %eax,%r13d
  movsbl %r13b,%eax
  cmp    $0x5c,%eax
  je     L999
  cmp    $0x5c,%eax
  jg     L993
  cmp    $0x5b,%eax
  je     L72
  cmp    $0x5b,%eax
  jg     L993
  cmp    $0x2a,%eax
  je     L725
  cmp    $0x3f,%eax
  jne    L993
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L378
  mov    $0x1,%eax
  jmp    L194
L378:
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L926
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  jne    L926
  mov    $0x1,%eax
  jmp    L194
L926:
  mov    -0x54(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  je     L503
  movzbl (%rbx),%eax
  cmp    $0x2e,%al
  jne    L503
  cmp    -0x50(%rbp),%rbx
  je     L67
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L503
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L503
L67:
  mov    $0x1,%eax
  jmp    L194
L999:
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L869
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L1020
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1020
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L180
L1020:
  mov    %r13d,%eax
L180:
  mov    %eax,%r13d
L869:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L1059
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1059
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L970
L1059:
  movzbl (%rbx),%eax
  movzbl %al,%eax
L970:
  movsbl %r13b,%edx
  cmp    %edx,%eax
  je     L389
  mov    $0x1,%eax
  jmp    L194
L725:
  mov    -0x54(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  je     L876
  movzbl (%rbx),%eax
  cmp    $0x2e,%al
  jne    L876
  cmp    -0x50(%rbp),%rbx
  je     L439
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L876
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L876
L439:
  mov    $0x1,%eax
  jmp    L194
L876:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  jmp    L1174
L272:
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L521
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  je     L396
L521:
  cmp    $0x3f,%r13b
  jne    L1148
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L1148
L396:
  mov    $0x1,%eax
  jmp    L194
L1148:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  add    $0x1,%rbx
L1174:
  cmp    $0x3f,%r13b
  je     L272
  cmp    $0x2a,%r13b
  je     L272
  test   %r13b,%r13b
  jne    L318
  mov    $0x0,%eax
  jmp    L194
L318:
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L147
  cmp    $0x5c,%r13b
  jne    L147
  movzbl (%r12),%eax
  jmp    L179
L147:
  mov    %r13d,%eax
L179:
  mov    %al,-0x31(%rbp)
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L493
  movzbl -0x31(%rbp),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L493
  movzbl -0x31(%rbp),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L481
L493:
  movzbl -0x31(%rbp),%eax
L481:
  mov    %al,-0x31(%rbp)
  sub    $0x1,%r12
  jmp    L253
L1035:
  cmp    $0x5b,%r13b
  je     L374
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L929
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L929
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L823
L929:
  movzbl (%rbx),%eax
  movzbl %al,%eax
L823:
  movsbl -0x31(%rbp),%edx
  cmp    %edx,%eax
  jne    L1158
L374:
  mov    -0x54(%rbp),%eax
  and    $0xfffffffb,%eax
  mov    %eax,%edx
  mov    %rbx,%rsi
  mov    %r12,%rdi
  mov    $0x0,%eax
  call   <fnmatch>
  test   %eax,%eax
  jne    L1158
  mov    $0x0,%eax
  jmp    L194
L1158:
  add    $0x1,%rbx
L253:
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L1035
  mov    $0x1,%eax
  jmp    L194
L72:
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L977
  mov    $0x1,%eax
  jmp    L194
L977:
  mov    -0x54(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  je     L641
  movzbl (%rbx),%eax
  cmp    $0x2e,%al
  jne    L641
  cmp    -0x50(%rbp),%rbx
  je     L492
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L641
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L641
L492:
  mov    $0x1,%eax
  jmp    L194
L641:
  movzbl (%r12),%eax
  cmp    $0x21,%al
  je     L922
  movzbl (%r12),%eax
  cmp    $0x5e,%al
  jne    L128
L922:
  mov    $0x1,%eax
  jmp    L898
L128:
  mov    $0x0,%eax
L898:
  mov    %eax,%r15d
  test   %r15d,%r15d
  je     L57
  add    $0x1,%r12
L57:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
L280:
  mov    %r13b,-0x55(%rbp)
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L332
  cmp    $0x5c,%r13b
  jne    L332
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r14d
  mov    %r14b,-0x55(%rbp)
L332:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L499
  movzbl -0x55(%rbp),%r14d
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L499
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L380
L499:
  movzbl -0x55(%rbp),%eax
L380:
  mov    %eax,%r14d
  mov    %r14b,-0x55(%rbp)
  test   %r13b,%r13b
  jne    L1034
  mov    $0x1,%eax
  jmp    L194
L1034:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L404
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L404
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L392
L404:
  mov    %r13d,%eax
L392:
  mov    %eax,%r13d
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L900
  cmp    $0x2f,%r13b
  jne    L900
  mov    $0x1,%eax
  jmp    L194
L900:
  cmp    $0x2d,%r13b
  jne    L1102
  movzbl (%r12),%eax
  cmp    $0x5d,%al
  je     L1102
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r14d
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L868
  cmp    $0x5c,%r14b
  jne    L868
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r14d
L868:
  test   %r14b,%r14b
  jne    L434
  mov    $0x1,%eax
  jmp    L194
L434:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L807
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L807
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L1
L807:
  mov    %r14d,%eax
L1:
  mov    %eax,%r14d
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
L1102:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L1259
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1259
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L1253
L1259:
  movzbl (%rbx),%eax
  movzbl %al,%eax
L1253:
  movsbl -0x55(%rbp),%edx
  cmp    %edx,%eax
  jl     L757
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L132
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L132
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L872
L132:
  movzbl (%rbx),%eax
  movzbl %al,%eax
L872:
  movsbl %r14b,%edx
  cmp    %edx,%eax
  jle    L3
L757:
  cmp    $0x5d,%r13b
  je     L92
  jmp    L280
L92:
  nop
  test   %r15d,%r15d
  jne    L1282
  mov    $0x1,%eax
  jmp    L194
L3:
  nop
  jmp    L1118
L1169:
  test   %r13b,%r13b
  jne    L766
  mov    $0x1,%eax
  jmp    L194
L766:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L1118
  cmp    $0x5c,%r13b
  jne    L1118
  add    $0x1,%r12
L1118:
  cmp    $0x5d,%r13b
  jne    L1169
  test   %r15d,%r15d
  je     L698
  mov    $0x1,%eax
  jmp    L194
L993:
  movsbl %r13b,%r13d
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L642
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L642
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L438
L642:
  movzbl (%rbx),%eax
  movzbl %al,%eax
L438:
  cmp    %r13d,%eax
  je     L687
  mov    $0x1,%eax
  jmp    L194
L503:
  nop
  jmp    L687
L389:
  nop
  jmp    L687
L1282:
  nop
  jmp    L687
L698:
  nop
L687:
  add    $0x1,%rbx
L1152:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  test   %r13b,%r13b
  jne    L386
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L400
  mov    $0x0,%eax
  jmp    L194
L400:
  mov    -0x54(%rbp),%eax
  and    $0x8,%eax
  test   %eax,%eax
  je     L437
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  jne    L437
  mov    $0x0,%eax
  jmp    L194
L437:
  mov    $0x1,%eax
L194:
  add    $0x38,%rsp
  pop    %rbx
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  pop    %rbp
  ret
```

assistant: ```c
int fnmatch(pattern, string, flags) const char *pattern;
const char *string;
int flags;
{
  register const char *p = pattern, *n = string;
  register char c;
  while ((c = *p++) != '\0') {
    c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)c)) ? tolower((unsigned char)c) : ((unsigned char)c));
    switch (c) {
    case '?':
      if (*n == '\0')
        return 1;
      else if ((flags & (1 << 0)) && *n == '/')
        return 1;
      else if ((flags & (1 << 2)) && *n == '.' && (n == string || ((flags & (1 << 0)) && n[-1] == '/')))
        return 1;
      break;
    case '\\':
      if (!(flags & (1 << 1))) {
        c = *p++;
        c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)c)) ? tolower((unsigned char)c) : ((unsigned char)c));
      }
      if (((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)) != c)
        return 1;
      break;
    case '*':
      if ((flags & (1 << 2)) && *n == '.' && (n == string || ((flags & (1 << 0)) && n[-1] == '/')))
        return 1;
      for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
        if (((flags & (1 << 0)) && *n == '/') || (c == '?' && *n == '\0'))
          return 1;
      if (c == '\0')
        return 0;
      {
        char c1 = (!(flags & (1 << 1)) && c == '\\') ? *p : c;
        c1 = ((flags & (1 << 4)) && (1 && isupper((unsigned char)c1)) ? tolower((unsigned char)c1) : ((unsigned char)c1));
        for (--p; *n != '\0'; ++n)
          if ((c == '[' || ((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)) == c1) && fnmatch(p, n, flags & ~(1 << 2)) == 0)
            return 0;
        return 1;
      }
    case '[': {
      register int not ;
      if (*n == '\0')
        return 1;
      if ((flags & (1 << 2)) && *n == '.' && (n == string || ((flags & (1 << 0)) && n[-1] == '/')))
        return 1;
      not = (*p == '!' || *p == '^');
      if (not )
        ++p;
      c = *p++;
      for (;;) {
        register char cstart = c, cend = c;
        if (!(flags & (1 << 1)) && c == '\\')
          cstart = cend = *p++;
        cstart = cend = ((flags & (1 << 4)) && (1 && isupper((unsigned char)cstart)) ? tolower((unsigned char)cstart) : ((unsigned char)cstart));
        if (c == '\0')
          return 1;
        c = *p++;
        c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)c)) ? tolower((unsigned char)c) : ((unsigned char)c));
        if ((flags & (1 << 0)) && c == '/')
          return 1;
        if (c == '-' && *p != ']') {
          cend = *p++;
          if (!(flags & (1 << 1)) && cend == '\\')
            cend = *p++;
          if (cend == '\0')
            return 1;
          cend = ((flags & (1 << 4)) && (1 && isupper((unsigned char)cend)) ? tolower((unsigned char)cend) : ((unsigned char)cend));
          c = *p++;
        }
        if (((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)) >= cstart && ((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)) <= cend)
          goto matched;
        if (c == ']')
          break;
      }
      if (!not )
        return 1;
      break;
    matched:;
      while (c != ']') {
        if (c == '\0')
          return 1;
        c = *p++;
        if (!(flags & (1 << 1)) && c == '\\')
          ++p;
      }
      if (not )
        return 1;
    } break;
    default:
      if (c != ((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)))
        return 1;
    }
    ++n;
  }
  if (*n == '\0')
    return 0;
  if ((flags & (1 << 3)) && *n == '/')
    return 0;
  return 1;
}
```