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

```asm
<fpattern_submatch>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  jmp    L561
L469:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,-0x1c(%rbp)
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,-0x18(%rbp)
  addq   $0x1,-0x38(%rbp)
  cmpl   $0x5c,-0x18(%rbp)
  je     L145
  cmpl   $0x5c,-0x18(%rbp)
  jg     L32
  cmpl   $0x5b,-0x18(%rbp)
  je     L447
  cmpl   $0x5b,-0x18(%rbp)
  jg     L32
  cmpl   $0x3f,-0x18(%rbp)
  je     L557
  cmpl   $0x3f,-0x18(%rbp)
  jg     L32
  cmpl   $0x2a,-0x18(%rbp)
  je     L81
  cmpl   $0x2a,-0x18(%rbp)
  jg     L32
  cmpl   $0x1a,-0x18(%rbp)
  je     L357
  cmpl   $0x21,-0x18(%rbp)
  je     L163
  jmp    L32
L557:
  cmpl   $0x0,-0x1c(%rbp)
  jne    L109
  mov    $0x0,%eax
  jmp    L331
L109:
  addq   $0x1,-0x40(%rbp)
  jmp    L561
L81:
  movl   $0x0,-0x2c(%rbp)
  jmp    L204
L130:
  addl   $0x1,-0x2c(%rbp)
L204:
  mov    -0x2c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L130
  jmp    L537
L608:
  mov    -0x2c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x40(%rbp),%rax
  add    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <fpattern_submatch>
  test   %eax,%eax
  je     L162
  mov    $0x1,%eax
  jmp    L331
L162:
  subl   $0x1,-0x2c(%rbp)
L537:
  cmpl   $0x0,-0x2c(%rbp)
  jns    L608
  mov    $0x0,%eax
  jmp    L331
L357:
  movl   $0x0,-0x2c(%rbp)
  jmp    L498
L595:
  addl   $0x1,-0x2c(%rbp)
L498:
  mov    -0x2c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L451
  mov    -0x2c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L595
  jmp    L451
L259:
  mov    -0x2c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x40(%rbp),%rax
  add    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <fpattern_submatch>
  test   %eax,%eax
  je     L23
  mov    $0x1,%eax
  jmp    L331
L23:
  subl   $0x1,-0x2c(%rbp)
L451:
  cmpl   $0x0,-0x2c(%rbp)
  jns    L259
  mov    $0x0,%eax
  jmp    L331
L145:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,-0x18(%rbp)
  mov    -0x1c(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  mov    -0x18(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  cmp    %eax,%ebx
  jne    L355
  cmpl   $0x0,-0x18(%rbp)
  jne    L94
L355:
  mov    $0x0,%eax
  jmp    L331
L94:
  addq   $0x1,-0x40(%rbp)
  addq   $0x1,-0x38(%rbp)
  jmp    L561
L447:
  movl   $0x1,-0x28(%rbp)
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x21,%al
  jne    L549
  addq   $0x1,-0x38(%rbp)
  movl   $0x0,-0x28(%rbp)
L549:
  cmpl   $0x0,-0x28(%rbp)
  sete   %al
  movzbl %al,%eax
  mov    %eax,-0x24(%rbp)
  jmp    L379
L215:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  jne    L442
  addq   $0x1,-0x38(%rbp)
L442:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L2
  mov    -0x38(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x38(%rbp)
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x14(%rbp),%eax
  mov    %eax,-0x20(%rbp)
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2d,%al
  jne    L319
  addq   $0x1,-0x38(%rbp)
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  jne    L440
  addq   $0x1,-0x38(%rbp)
L440:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L74
  mov    -0x38(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x38(%rbp)
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,-0x20(%rbp)
L319:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L83
  mov    -0x1c(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  mov    -0x14(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  cmp    %eax,%ebx
  jl     L379
  mov    -0x1c(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  cmp    %eax,%ebx
  jg     L379
  mov    -0x28(%rbp),%eax
  mov    %eax,-0x24(%rbp)
L379:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5d,%al
  je     L30
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L215
  jmp    L30
L2:
  nop
  jmp    L30
L74:
  nop
  jmp    L30
L83:
  nop
L30:
  cmpl   $0x0,-0x24(%rbp)
  jne    L201
  mov    $0x0,%eax
  jmp    L331
L201:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L38
  mov    $0x0,%eax
  jmp    L331
L38:
  addq   $0x1,-0x40(%rbp)
  addq   $0x1,-0x38(%rbp)
  jmp    L561
L163:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L418
  mov    $0x0,%eax
  jmp    L331
L418:
  mov    -0x40(%rbp),%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <fpattern_submatch>
  mov    %eax,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  sete   %al
  movzbl %al,%eax
  jmp    L331
L32:
  mov    -0x1c(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  mov    -0x18(%rbp),%eax
  mov    %eax,%edi
  call   <tolower@plt>
  cmp    %eax,%ebx
  je     L380
  mov    $0x0,%eax
  jmp    L331
L380:
  addq   $0x1,-0x40(%rbp)
  nop
L561:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L469
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L132
  mov    $0x0,%eax
  jmp    L331
L132:
  mov    $0x1,%eax
L331:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
int fpattern_submatch(const char *pat, const char *fname) {
  int fch;
  int pch;
  int i;
  int yes, match;
  int lo, hi;
  while (*pat != '\0') {
    fch = *fname;
    pch = *pat;
    pat++;
    switch (pch) {
    case '?':
      if (fch == '\0')
        return (0);
      fname++;
      break;
    case '*':
      i = 0;
      while (fname[i] != '\0')
        i++;
      while (i >= 0) {
        if (fpattern_submatch(pat, fname + i))
          return (1);
        i--;
      }
      return (0);
    case '\x1A':
      i = 0;
      while (fname[i] != '\0' && fname[i] != '.')
        i++;
      while (i >= 0) {
        if (fpattern_submatch(pat, fname + i))
          return (1);
        i--;
      }
      return (0);
    case '\\':
      pch = *pat;
      if (tolower(fch) != tolower(pch) || pch == '\0')
        return (0);
      fname++;
      pat++;
      break;
    case '[':
      yes = 1;
      if (*pat == '!') {
        pat++;
        yes = 0;
      }
      match = !yes;
      while (*pat != ']' && *pat != '\0') {
        if (*pat == '\\')
          pat++;
        if (*pat == '\0')
          break;
        lo = *pat++;
        hi = lo;
        if (*pat == '-') {
          pat++;
          if (*pat == '\\')
            pat++;
          if (*pat == '\0')
            break;
          hi = *pat++;
        }
        if (*pat == '\0')
          break;
        if (tolower(fch) >= tolower(lo) && tolower(fch) <= tolower(hi))
          match = yes;
      }
      if (!match)
        return (0);
      if (*pat == '\0')
        return (0);
      fname++;
      pat++;
      break;
    case '!':
      if (*pat == '\0')
        return (0);
      i = fpattern_submatch(pat, fname);
      return !i;
    default:
      if (tolower(fch) != tolower(pch))
        return (0);
      fname++;
      break;
    }
  }
  if (*fname != '\0')
    return (0);
  return (1);
}
```