user: 请从给定的汇编指令推导出C源代码:

```asm
<is_fido_security_token_desc>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  movl   $0x0,-0x2c(%rbp)
  movq   $0x0,-0x18(%rbp)
  jmp    L169
L88:
  mov    -0x18(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%eax
  cmp    $0xfe,%eax
  jne    L158
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  cmp    %rax,-0x40(%rbp)
  ja     L180
  mov    D3(%rip),%rax
  mov    (%rax),%eax
  neg    %eax
  jmp    L99
L180:
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%eax
  add    $0x3,%eax
  cltq
  add    %rax,-0x18(%rbp)
  jmp    L169
L158:
  mov    -0x18(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%eax
  sar    $0x4,%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x18(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%eax
  sar    $0x2,%eax
  and    $0x3,%eax
  mov    %eax,-0x20(%rbp)
  mov    -0x18(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%eax
  and    $0x3,%eax
  mov    %eax,-0x1c(%rbp)
  cmpl   $0x2,-0x1c(%rbp)
  jg     L55
  mov    -0x1c(%rbp),%eax
  cltq
  jmp    L70
L55:
  mov    $0x4,%eax
L70:
  mov    %rax,-0x8(%rbp)
  addq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  cmp    %rax,-0x40(%rbp)
  jae    L57
  mov    D3(%rip),%rax
  mov    (%rax),%eax
  neg    %eax
  jmp    L99
L57:
  movl   $0x0,-0x28(%rbp)
  movq   $0x0,-0x10(%rbp)
  jmp    L146
L189:
  mov    -0x18(%rbp),%rdx
  mov    -0x10(%rbp),%rax
  add    %rdx,%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%edx
  mov    -0x10(%rbp),%rax
  shl    $0x3,%eax
  mov    %eax,%ecx
  shl    %cl,%edx
  mov    %edx,%eax
  or     %eax,-0x28(%rbp)
  addq   $0x1,-0x10(%rbp)
L146:
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jb     L189
  mov    -0x8(%rbp),%rax
  add    %rax,-0x18(%rbp)
  cmpl   $0x1,-0x20(%rbp)
  jne    L64
  cmpl   $0x0,-0x24(%rbp)
  jne    L64
  cmpq   $0x2,-0x8(%rbp)
  jbe    L87
  mov    D3(%rip),%rax
  mov    (%rax),%eax
  neg    %eax
  jmp    L99
L87:
  mov    -0x28(%rbp),%eax
  shl    $0x10,%eax
  mov    %eax,-0x2c(%rbp)
L64:
  cmpl   $0x2,-0x20(%rbp)
  jne    L169
  cmpl   $0x0,-0x24(%rbp)
  jne    L169
  cmpq   $0x4,-0x8(%rbp)
  jne    L24
  mov    -0x28(%rbp),%eax
  mov    %eax,-0x2c(%rbp)
  jmp    L209
L24:
  mov    -0x2c(%rbp),%eax
  mov    $0x0,%ax
  mov    %eax,%edx
  mov    -0x28(%rbp),%eax
  movzwl %ax,%eax
  or     %edx,%eax
  mov    %eax,-0x2c(%rbp)
L209:
  cmpl   $0xf1d00001,-0x2c(%rbp)
  jne    L169
  mov    $0x1,%eax
  jmp    L99
L169:
  mov    -0x18(%rbp),%rax
  cmp    -0x40(%rbp),%rax
  jb     L88
  mov    $0x0,%eax
L99:
  pop    %rbp
  ret
```

assistant: ```c
int is_fido_security_token_desc(const uint8_t *desc, size_t desc_len) {
  uint32_t usage = 0;
  for (size_t pos = 0; pos < desc_len;) {
    uint8_t tag, type, size_code;
    size_t size;
    uint32_t value;
    if (desc[pos] == 0xfeu) {
      if (pos + 1 >= desc_len)
        return -EINVAL;
      pos += desc[pos + 1] + 3;
      continue;
    }
    tag = desc[pos] >> 4;
    type = (desc[pos] >> 2) & 0x3;
    size_code = desc[pos] & 0x3;
    size = size_code < 3 ? size_code : 4;
    pos++;
    if (pos + size > desc_len)
      return -EINVAL;
    value = 0;
    for (size_t i = 0; i < size; i++)
      value |= (uint32_t)desc[pos + i] << (8 * i);
    pos += size;
    if (type == 0x1u && tag == 0x0u) {
      if (size > 2)
        return -EINVAL;
      usage = (value & 0x0000ffffu) << 16;
    }
    if (type == 0x2u && tag == 0x0u) {
      if (size == 4)
        usage = value;
      else
        usage = (usage & 0xffff0000u) | (value & 0x0000ffffu);
      if (usage == 0xf1d00001u)
        return 1;
    }
  }
  return 0;
}
```