user: 下面的汇编指令对应的C源代码是什么:

```asm
<CheckUserinfo>:
  endbr64
  push   %rbp
  mov    %rsi,%rdi
  mov    %rsi,%rbp
  push   %rbx
  sub    $0x8,%rsp
  call   <strlen@plt>
  mov    %rax,%rbx
  lea    D17(%rip),%rax
  test   %ebx,%ebx
  jle    L29
  lea    D16(%rip),%rax
  cmp    $0x3d4,%ebx
  jg     L29
  movzbl 0x0(%rbp),%edi
  lea    D118(%rip),%rax
  cmp    $0x5c,%dil
  jne    L29
  movslq %ebx,%rdx
  lea    D33(%rip),%rax
  cmpb   $0x5c,-0x1(%rbp,%rdx,1)
  je     L29
  lea    0x1(%rbp),%rsi
  mov    $0x5c,%eax
  xor    %ecx,%ecx
  mov    %rsi,%rdx
  nopw   0x0(%rax,%rax,1)
L84:
  cmp    $0x5c,%al
  sete   %al
  add    $0x1,%rdx
  movzbl %al,%eax
  add    %eax,%ecx
  movzbl -0x1(%rdx),%eax
  test   %al,%al
  jne    L84
  and    $0x1,%ecx
  lea    D119(%rip),%rax
  jne    L29
  lea    D168(%rip),%rax
  cmp    $0x4,%ebx
  jle    L29
  movzbl 0x3(%rbp),%edx
  test   %dl,%dl
  je     L29
  xor    %ecx,%ecx
  jmp    L441
  nopw   0x0(%rax,%rax,1)
L109:
  movzbl 0x3(%rsi),%edx
  test   %dl,%dl
  je     L427
  movzbl (%rsi),%edi
  add    $0x1,%rsi
L441:
  cmp    $0x5c,%dil
  jne    L109
  cmpb   $0x69,(%rsi)
  jne    L109
  cmpb   $0x70,0x1(%rsi)
  jne    L109
  cmp    $0x5c,%dl
  sete   %al
  cmp    $0x1,%al
  sbb    $0xffffffff,%ecx
  jmp    L109
  nopl   (%rax)
L427:
  lea    D168(%rip),%rax
  test   %ecx,%ecx
  je     L29
  lea    D158(%rip),%rax
  cmp    $0x1,%ecx
  je     L372
L29:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  ret
  cs nopw 0x0(%rax,%rax,1)
L372:
  lea    D68(%rip),%rsi
  mov    %rbp,%rdi
  xor    %eax,%eax
  call   <Info_ValueForKey@plt>
  mov    %eax,%edi
  xor    %eax,%eax
  call   <GetParsedIP@plt>
  mov    %eax,%r8d
  lea    D105(%rip),%rax
  test   %r8d,%r8d
  je     L29
  cmp    $0x9,%ebx
  jle    L267
  movzbl 0x8(%rbp),%edx
  test   %dl,%dl
  je     L341
  mov    %rbp,%rax
  xor    %ecx,%ecx
  jmp    L545
  nopl   (%rax)
L613:
  movzbl 0x9(%rax),%edx
  add    $0x1,%rax
  test   %dl,%dl
  je     L530
L545:
  cmpb   $0x5c,(%rax)
  jne    L613
  cmpb   $0x63,0x1(%rax)
  jne    L613
  cmpb   $0x6c,0x2(%rax)
  jne    L613
  cmpb   $0x5f,0x3(%rax)
  jne    L613
  cmpb   $0x67,0x4(%rax)
  jne    L613
  cmpb   $0x75,0x5(%rax)
  jne    L613
  cmpb   $0x69,0x6(%rax)
  jne    L613
  cmpb   $0x64,0x7(%rax)
  jne    L613
  cmp    $0x5c,%dl
  sete   %dl
  cmp    $0x1,%dl
  sbb    $0xffffffff,%ecx
  jmp    L613
  nopl   (%rax)
L267:
  lea    D66(%rip),%rax
  cmp    $0x6,%ebx
  jle    L29
L341:
  movzbl 0x5(%rbp),%edx
  lea    D66(%rip),%rax
  test   %dl,%dl
  je     L29
  mov    %rbp,%rcx
  mov    %rbp,%rax
  xor    %esi,%esi
  jmp    L339
  nopl   (%rax)
L330:
  movzbl 0x6(%rax),%edx
  add    $0x1,%rax
  test   %dl,%dl
  je     L576
L339:
  cmpb   $0x5c,(%rax)
  jne    L330
  cmpb   $0x6e,0x1(%rax)
  jne    L330
  cmpb   $0x61,0x2(%rax)
  jne    L330
  cmpb   $0x6d,0x3(%rax)
  jne    L330
  cmpb   $0x65,0x4(%rax)
  jne    L330
  cmp    $0x5c,%dl
  sete   %dl
  cmp    $0x1,%dl
  sbb    $0xffffffff,%esi
  jmp    L330
  nopw   0x0(%rax,%rax,1)
L576:
  lea    D66(%rip),%rax
  test   %esi,%esi
  je     L29
  lea    D42(%rip),%rax
  cmp    $0x1,%esi
  jne    L29
  cmp    $0xf,%ebx
  jle    L525
  movzbl 0xe(%rbp),%eax
  test   %al,%al
  je     L525
  xor    %edx,%edx
  jmp    L63
L252:
  movzbl 0xf(%rcx),%eax
  add    $0x1,%rcx
  test   %al,%al
  je     L150
L63:
  cmpb   $0x5c,(%rcx)
  jne    L252
  cmpb   $0x63,0x1(%rcx)
  jne    L252
  cmpb   $0x6c,0x2(%rcx)
  jne    L252
  cmpb   $0x5f,0x3(%rcx)
  jne    L252
  cmpb   $0x70,0x4(%rcx)
  jne    L252
  cmpb   $0x75,0x5(%rcx)
  jne    L252
  cmpb   $0x6e,0x6(%rcx)
  jne    L252
  cmpb   $0x6b,0x7(%rcx)
  jne    L252
  cmpb   $0x62,0x8(%rcx)
  jne    L252
  cmpb   $0x75,0x9(%rcx)
  jne    L252
  cmpb   $0x73,0xa(%rcx)
  jne    L252
  cmpb   $0x74,0xb(%rcx)
  jne    L252
  cmpb   $0x65,0xc(%rcx)
  jne    L252
  cmpb   $0x72,0xd(%rcx)
  jne    L252
  cmp    $0x5c,%al
  sete   %al
  cmp    $0x1,%al
  sbb    $0xffffffff,%edx
  jmp    L252
  nopl   0x0(%rax,%rax,1)
L530:
  lea    D91(%rip),%rax
  cmp    $0x1,%ecx
  jle    L341
  jmp    L29
L150:
  lea    D133(%rip),%rax
  cmp    $0x1,%edx
  jg     L29
L525:
  lea    D116(%rip),%rsi
  mov    %rbp,%rdi
  xor    %eax,%eax
  call   <Info_ValueForKey@plt>
  movslq %eax,%rdx
  lea    D145(%rip),%rax
  test   %edx,%edx
  je     L29
  cmpb   $0x0,(%rdx)
  mov    $0x0,%edx
  cmovne %rdx,%rax
  jmp    L29
```

tool_calls: name: extract_symbolic_data
arguments: label: D17
type: string
name: extract_symbolic_data
arguments: label: D16
type: string
name: extract_symbolic_data
arguments: label: D118
type: string
name: extract_symbolic_data
arguments: label: D33
type: string
name: extract_symbolic_data
arguments: label: D119
type: string
name: extract_symbolic_data
arguments: label: D168
type: string
name: extract_symbolic_data
arguments: label: D158
type: string
name: extract_symbolic_data
arguments: label: D68
type: string
name: extract_symbolic_data
arguments: label: D105
type: string
name: extract_symbolic_data
arguments: label: D66
type: string
name: extract_symbolic_data
arguments: label: D42
type: string
name: extract_symbolic_data
arguments: label: D91
type: string
name: extract_symbolic_data
arguments: label: D133
type: string
name: extract_symbolic_data
arguments: label: D116
type: string
name: extract_symbolic_data
arguments: label: D145
type: string

tool: D17: Userinfo too short

tool: D16: Userinfo too long.

tool: D118: Missing leading slash in userinfo.

tool: D33: Trailing slash in userinfo.

tool: D119: Bad number of slashes in userinfo.

tool: D168: Missing IP in userinfo.

tool: D158: Too many IP fields in userinfo.

tool: D68: ip

tool: D105: Malformed IP in userinfo.

tool: D66: Missing name field in userinfo.

tool: D42: Too many name fields in userinfo.

tool: D91: Too many cl_guid fields in userinfo.

tool: D133: Too many cl_punkbuster fields in userinfo.

tool: D116: rate

tool: D145: Wrong rate field in userinfo.

assistant: ```c
char *CheckUserinfo(int clientNum, char *userinfo) {
  char *value;
  int length = strlen(userinfo);
  int i, slashCount = 0, count = 0;
  if (length < 1) {
    return "Userinfo too short";
  }
  if (length > 1024 - 44) {
    return "Userinfo too long.";
  }
  if (userinfo[0] != '\\') {
    return "Missing leading slash in userinfo.";
  }
  if (userinfo[length - 1] == '\\') {
    return "Trailing slash in userinfo.";
  }
  for (i = 0; userinfo[i]; ++i) {
    if (userinfo[i] == '\\') {
      slashCount++;
    }
  }
  if (slashCount % 2 != 0) {
    return "Bad number of slashes in userinfo.";
  }
  if (length > 4) {
    for (i = 0; userinfo[i + 3]; ++i) {
      if (userinfo[i] == '\\' && userinfo[i + 1] == 'i' && userinfo[i + 2] == 'p' && userinfo[i + 3] == '\\') {
        count++;
      }
    }
  }
  if (count == 0) {
    return "Missing IP in userinfo.";
  } else if (count > 1) {
    return "Too many IP fields in userinfo.";
  } else {
    if (GetParsedIP(Info_ValueForKey(userinfo, "ip")) == ((void *)0)) {
      return "Malformed IP in userinfo.";
    }
  }
  count = 0;
  if (length > 9) {
    for (i = 0; userinfo[i + 8]; ++i) {
      if (userinfo[i] == '\\' && userinfo[i + 1] == 'c' && userinfo[i + 2] == 'l' && userinfo[i + 3] == '_' && userinfo[i + 4] == 'g' && userinfo[i + 5] == 'u' && userinfo[i + 6] == 'i' && userinfo[i + 7] == 'd' && userinfo[i + 8] == '\\') {
        count++;
      }
    }
  }
  if (count > 1) {
    return "Too many cl_guid fields in userinfo.";
  }
  count = 0;
  if (length > 6) {
    for (i = 0; userinfo[i + 5]; ++i) {
      if (userinfo[i] == '\\' && userinfo[i + 1] == 'n' && userinfo[i + 2] == 'a' && userinfo[i + 3] == 'm' && userinfo[i + 4] == 'e' && userinfo[i + 5] == '\\') {
        count++;
      }
    }
  }
  if (count == 0) {
    return "Missing name field in userinfo.";
  } else if (count > 1) {
    return "Too many name fields in userinfo.";
  }
  count = 0;
  if (length > 15) {
    for (i = 0; userinfo[i + 14]; ++i) {
      if (userinfo[i] == '\\' && userinfo[i + 1] == 'c' && userinfo[i + 2] == 'l' && userinfo[i + 3] == '_' && userinfo[i + 4] == 'p' && userinfo[i + 5] == 'u' && userinfo[i + 6] == 'n' && userinfo[i + 7] == 'k' && userinfo[i + 8] == 'b' && userinfo[i + 9] == 'u' && userinfo[i + 10] == 's' && userinfo[i + 11] == 't' && userinfo[i + 12] == 'e' && userinfo[i + 13] == 'r' && userinfo[i + 14] == '\\') {
        count++;
      }
    }
  }
  if (count > 1) {
    return "Too many cl_punkbuster fields in userinfo.";
  }
  value = Info_ValueForKey(userinfo, "rate");
  if (value == ((void *)0) || value[0] == '\0') {
    return "Wrong rate field in userinfo.";
  }
  return 0;
}
```