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

```asm
<LookupStringInFixedSet>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %rdx,-0x58(%rbp)
  mov    %rcx,-0x60(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x48(%rbp),%rdx
  mov    -0x50(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x30(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x58(%rbp),%rdx
  mov    -0x60(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x10(%rbp)
  movq   $0x0,-0x20(%rbp)
  jmp    L155
L158:
  movl   $0x0,-0x34(%rbp)
  mov    -0x58(%rbp),%rax
  cmp    %rax,-0x10(%rbp)
  je     L149
  mov    -0x28(%rbp),%rax
  mov    -0x18(%rbp),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <IsEOL@plt>
  test   %eax,%eax
  jne    L149
  mov    -0x20(%rbp),%rcx
  mov    -0x58(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    -0x18(%rbp),%rsi
  mov    %rax,%rdi
  call   <IsMatch@plt>
  test   %eax,%eax
  jne    L165
  jmp    L155
L165:
  movl   $0x1,-0x34(%rbp)
  lea    -0x20(%rbp),%rdx
  lea    -0x58(%rbp),%rcx
  lea    -0x28(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <NextPos@plt>
  jmp    L47
L3:
  mov    -0x20(%rbp),%rcx
  mov    -0x58(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    -0x18(%rbp),%rsi
  mov    %rax,%rdi
  call   <IsMatch@plt>
  test   %eax,%eax
  jne    L14
  mov    $0xffffffff,%eax
  jmp    L91
L14:
  lea    -0x20(%rbp),%rdx
  lea    -0x58(%rbp),%rcx
  lea    -0x28(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <NextPos@plt>
L47:
  mov    -0x28(%rbp),%rax
  mov    -0x18(%rbp),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <IsEOL@plt>
  test   %eax,%eax
  jne    L149
  mov    -0x58(%rbp),%rax
  cmp    %rax,-0x10(%rbp)
  jne    L3
L149:
  mov    -0x58(%rbp),%rax
  cmp    %rax,-0x10(%rbp)
  jne    L140
  mov    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    -0x38(%rbp),%rcx
  mov    -0x18(%rbp),%rsi
  mov    %rax,%rdi
  call   <GetReturnValue@plt>
  test   %rax,%rax
  je     L183
  mov    -0x38(%rbp),%eax
  jmp    L91
L183:
  cmpl   $0x0,-0x34(%rbp)
  je     L155
  mov    $0xffffffff,%eax
  jmp    L91
L140:
  mov    -0x20(%rbp),%rcx
  mov    -0x58(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    -0x18(%rbp),%rsi
  mov    %rax,%rdi
  call   <IsEndCharMatch@plt>
  test   %eax,%eax
  jne    L75
  cmpl   $0x0,-0x34(%rbp)
  je     L155
  mov    $0xffffffff,%eax
  jmp    L91
L75:
  lea    -0x20(%rbp),%rdx
  lea    -0x58(%rbp),%rcx
  lea    -0x28(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <NextPos@plt>
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x30(%rbp)
L155:
  lea    -0x28(%rbp),%rdx
  mov    -0x18(%rbp),%rcx
  lea    -0x30(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <GetNextOffset@plt>
  test   %rax,%rax
  jne    L158
  mov    $0xffffffff,%eax
L91:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L73
  call   <__stack_chk_fail@plt>
L73:
  leave
  ret
```

assistant: ```c
int LookupStringInFixedSet(const unsigned char *graph, size_t length, const char *key, size_t key_length) {
  const unsigned char *pos = graph;
  const unsigned char *end = graph + length;
  const unsigned char *offset = pos;
  const char *key_end = key + key_length;
  const char *multibyte_start = 0;
  while (GetNextOffset(&pos, end, &offset)) {
    int did_consume = 0;
    if (key != key_end && !IsEOL(offset, end)) {
      if (!IsMatch(offset, end, key, multibyte_start))
        continue;
      did_consume = 1;
      NextPos(&offset, &key, &multibyte_start);
      while (!IsEOL(offset, end) && key != key_end) {
        if (!IsMatch(offset, end, key, multibyte_start))
          return -1;
        NextPos(&offset, &key, &multibyte_start);
      }
    }
    if (key == key_end) {
      int return_value;
      if (GetReturnValue(offset, end, multibyte_start, &return_value))
        return return_value;
      if (did_consume)
        return -1;
      continue;
    }
    if (!IsEndCharMatch(offset, end, key, multibyte_start)) {
      if (did_consume)
        return -1;
      continue;
    }
    NextPos(&offset, &key, &multibyte_start);
    pos = offset;
  }
  return -1;
}
```