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

```asm
<stok>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x20,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L116
  movl   $0x0,-0xc(%rbp)
  jmp    L397
L116:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isspace@plt>
  test   %rax,%rax
  je     L3
  nop
L162:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isspace@plt>
  test   %rax,%rax
  jne    L162
  movl   $0x1,-0xc(%rbp)
  jmp    L397
L3:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L188
  movl   $0x2,-0xc(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x30,%al
  jne    L151
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x78,%al
  je     L19
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x58,%al
  jne    L151
L19:
  addq   $0x1,-0x8(%rbp)
  nop
L339:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isxdigit@plt>
  test   %rax,%rax
  jne    L339
  jmp    L397
L151:
  nop
L294:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L294
  nop
  jmp    L247
L239:
  nop
L247:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L134
  movl   $0x3,-0xc(%rbp)
  nop
L224:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L224
L134:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x65,%al
  je     L10
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x45,%al
  jne    L397
L10:
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x2b,%al
  je     L198
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x2d,%al
  jne    L62
L198:
  addq   $0x1,-0x8(%rbp)
L62:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L297
  movl   $0xffffffff,-0xc(%rbp)
  jmp    L397
L297:
  nop
L130:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L130
  jmp    L397
L188:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L272
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L239
L272:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x27,%al
  je     L261
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x22,%al
  jne    L164
L261:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0xd(%rbp)
  movl   $0x6,-0xc(%rbp)
  jmp    L54
L204:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  jne    L372
  addq   $0x1,-0x8(%rbp)
L372:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L54
  movl   $0xffffffff,-0xc(%rbp)
  subq   $0x1,-0x8(%rbp)
  jmp    L348
L54:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    %al,-0xd(%rbp)
  jne    L204
L348:
  addq   $0x1,-0x8(%rbp)
  jmp    L397
L164:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5f,%al
  je     L303
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isalpha@plt>
  test   %rax,%rax
  je     L178
L303:
  nop
L154:
  addq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5f,%al
  je     L154
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isalnum@plt>
  test   %rax,%rax
  jne    L154
  movl   $0x4,-0xc(%rbp)
  jmp    L397
L178:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <ispunct@plt>
  test   %rax,%rax
  je     L209
  addq   $0x1,-0x8(%rbp)
  movl   $0x5,-0xc(%rbp)
  jmp    L397
L209:
  movl   $0xffffffff,-0xc(%rbp)
L397:
  cmpq   $0x0,-0x20(%rbp)
  je     L142
  mov    -0x20(%rbp),%rax
  mov    -0x8(%rbp),%rdx
  mov    %rdx,(%rax)
L142:
  mov    -0xc(%rbp),%eax
  leave
  ret
```

assistant: ```c
int stok(const char *s, char **endptr) {
  int rc;
  const char *t = s;
  if (*t == '\0') {
    rc = 0;
  } else if (isspace(*t)) {
    while (isspace(*++t))
      ;
    rc = 1;
  } else if (isdigit(*t)) {
    rc = 2;
    if (*t == '0' && (t[1] == 'x' || t[1] == 'X')) {
      ++t;
      while (isxdigit(*++t))
        ;
    } else {
      while (isdigit(*++t))
        ;
    tok_float:
      if (*t == '.') {
        rc = 3;
        while (isdigit(*++t))
          ;
      }
      if (*t == 'e' || *t == 'E') {
        if (t[1] == '+' || t[1] == '-')
          ++t;
        if (!isdigit(*++t)) {
          rc = (-1);
        } else {
          while (isdigit(*++t))
            ;
        }
      }
    }
  } else if (*t == '.' && isdigit(t[1])) {
    goto tok_float;
  } else if (*t == '\'' || *t == '"') {
    char delimiter = *t;
    rc = 6;
    while (*++t != delimiter) {
      if (*t == '\\')
        ++t;
      if (*t == '\0') {
        rc = (-1);
        --t;
        break;
      }
    }
    ++t;
  } else if (*t == '_' || isalpha(*t)) {
    while (*++t == '_' || isalnum(*t))
      ;
    rc = 4;
  } else if (ispunct(*t)) {
    ++t;
    rc = 5;
  } else {
    rc = (-1);
  }
  if (endptr) {
    *endptr = (char *)t;
  }
  return rc;
}
```