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

```asm
<get_keyword_visual>:
  endbr64
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %rdi,%rbp
  push   %rbx
  sub    $0x90,%rsp
  movzbl (%rdi),%edx
  mov    %fs:0x28,%rax
  mov    %rax,0x88(%rsp)
  xor    %eax,%eax
  cmp    $0x20,%dl
  jne    L261
  mov    $0x1,%eax
  nopw   0x0(%rax,%rax,1)
L132:
  mov    %eax,%r12d
  add    $0x1,%rax
  movzbl -0x1(%rbp,%rax,1),%edx
  cmp    $0x20,%dl
  je     L132
  add    $0x1,%r12d
  movslq %r12d,%rbx
L146:
  cmp    $0x21,%dl
  je     L182
  lea    D38(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
L182:
  movzbl 0x0(%rbp,%rbx,1),%edx
  cmp    $0x2c,%dl
  ja     L174
  movabs $0xffffeffefffffbff,%rax
  bt     %rdx,%rax
  jae    L247
L174:
  movslq %r12d,%rsi
  mov    $0x1,%eax
  lea    -0x1(%rsp),%rcx
  movabs $0xffffeffefffffbff,%r8
  add    %rbp,%rsi
  nopl   0x0(%rax)
L349:
  mov    %dl,(%rcx,%rax,1)
  movzbl (%rsi,%rax,1),%edx
  lea    (%r12,%rax,1),%ebx
  movslq %eax,%rdi
  add    $0x1,%rax
  cmp    $0x2c,%dl
  ja     L349
  bt     %rdx,%r8
  jb     L349
L19:
  mov    %rsp,%r12
  movb   $0x0,(%rsp,%rdi,1)
  mov    %r12,%rdi
  call   <strlen@plt>
  test   %eax,%eax
  jle    L98
  sub    $0x1,%eax
  mov    %r12,%r13
  lea    0x1(%rsp,%rax,1),%r14
  nopl   0x0(%rax,%rax,1)
L2:
  movsbl 0x0(%r13),%edi
  add    $0x1,%r13
  call   <tolower@plt>
  mov    %al,-0x1(%r13)
  cmp    %r13,%r14
  jne    L2
L98:
  mov    $0x6,%edx
  lea    D48(%rip),%rsi
  mov    %r12,%rdi
  call   <strncmp@plt>
  test   %rax,%rax
  jne    L181
L354:
  movslq %ebx,%rax
  movzbl 0x0(%rbp,%rax,1),%edx
  cmp    $0x3d,%dl
  je     L196
  cmp    $0xa,%dl
  lea    0x1(%rbx),%eax
  setne  %cl
  cltq
  test   %cl,%cl
  je     L196
  nopl   0x0(%rax,%rax,1)
L31:
  movzbl 0x0(%rbp,%rax,1),%edx
  mov    %eax,%ebx
  add    $0x1,%rax
  cmp    $0x3d,%dl
  je     L196
  cmp    $0xa,%dl
  jne    L31
L126:
  lea    D16(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
  jmp    L339
  nopl   0x0(%rax,%rax,1)
L196:
  cmp    $0xa,%dl
  je     L126
L339:
  lea    0x1(%rbx),%r14d
  movslq %r14d,%r13
  add    %rbp,%r13
  movzbl 0x0(%r13),%edx
  cmp    $0x20,%dl
  jne    L271
  lea    0x2(%rbx),%eax
  cltq
  cs nopw 0x0(%rax,%rax,1)
L356:
  mov    %eax,%r14d
  lea    0x0(%rbp,%rax,1),%r13
  add    $0x1,%rax
  movzbl -0x1(%rbp,%rax,1),%edx
  cmp    $0x20,%dl
  je     L356
L271:
  cmp    $0xa,%dl
  je     L142
L221:
  movzbl 0x0(%r13),%edx
  cmp    $0x3d,%dl
  ja     L278
  movabs $0xdfffeffefffffbff,%rax
  xor    %esi,%esi
  bt     %rdx,%rax
  jae    L135
L278:
  movslq %r14d,%r13
  mov    $0x1,%eax
  lea    -0x1(%rsp),%rcx
  movabs $0xdfffeffefffffbff,%rdi
  add    %r13,%rbp
  nopl   (%rax)
L362:
  mov    %dl,(%rcx,%rax,1)
  movzbl 0x0(%rbp,%rax,1),%edx
  movslq %eax,%rsi
  add    $0x1,%rax
  cmp    $0x3d,%dl
  ja     L362
  bt     %rdx,%rdi
  jb     L362
L135:
  mov    %r12,%rdi
  movb   $0x0,(%rsp,%rsi,1)
  call   <strlen@plt>
  test   %eax,%eax
  jle    L136
  sub    $0x1,%eax
  mov    %r12,%rbx
  lea    0x1(%rsp,%rax,1),%rbp
  nopl   (%rax)
L259:
  movsbl (%rbx),%edi
  add    $0x1,%rbx
  call   <tolower@plt>
  mov    %al,-0x1(%rbx)
  cmp    %rbp,%rbx
  jne    L259
L136:
  mov    $0x3,%edx
  lea    D52(%rip),%rsi
  mov    %r12,%rdi
  call   <strncmp@plt>
  test   %rax,%rax
  je     L41
  mov    $0x3,%edx
  lea    D50(%rip),%rsi
  mov    %r12,%rdi
  call   <strncmp@plt>
  test   %rax,%rax
  je     L41
  mov    $0x3,%edx
  lea    D58(%rip),%rsi
  mov    %r12,%rdi
  call   <strncmp@plt>
  test   %rax,%rax
  je     L176
  mov    $0x3,%edx
  lea    D94(%rip),%rsi
  mov    %r12,%rdi
  call   <strncmp@plt>
  test   %rax,%rax
  je     L176
  lea    D82(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
  xor    %eax,%eax
  jmp    L83
  nopl   0x0(%rax)
L41:
  mov    $0x1,%eax
L83:
  mov    0x88(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L300
  add    $0x90,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
  nopl   0x0(%rax)
L181:
  mov    $0x6,%edx
  lea    D64(%rip),%rsi
  mov    %r12,%rdi
  call   <strncmp@plt>
  mov    %rax,%r8
  xor    %eax,%eax
  test   %r8,%r8
  je     L354
  jmp    L83
  nopl   0x0(%rax)
L247:
  mov    %r12d,%ebx
  xor    %edi,%edi
  jmp    L19
  nopw   0x0(%rax,%rax,1)
L176:
  mov    $0x2,%eax
  jmp    L83
  nop
L142:
  lea    D16(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
  jmp    L221
  nopl   0x0(%rax)
L261:
  mov    $0x1,%ebx
  mov    $0x1,%r12d
  jmp    L146
L300:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: tag: D38
data_type: string
name: unpack_data
arguments: tag: D48
data_type: string
name: unpack_data
arguments: tag: D16
data_type: string
name: unpack_data
arguments: tag: D52
data_type: string
name: unpack_data
arguments: tag: D50
data_type: string
name: unpack_data
arguments: tag: D58
data_type: string
name: unpack_data
arguments: tag: D94
data_type: string
name: unpack_data
arguments: tag: D82
data_type: string
name: unpack_data
arguments: tag: D64
data_type: string

tool: D38: ERROR: HEC-MW-VIS-E0002: The control parameter format error: should start from !

tool: D48: VISUAL

tool: D16: ERROR: HEC-MW-VIS-E0006:The control parameter format error: visual ID

tool: D52: PSR

tool: D50: psr

tool: D58: PVR

tool: D94: pvr

tool: D82: ERROR: HEC-MW-VIS-E0007:The control parameter format error: method only can be PSR or PVR

tool: D64: visual

assistant: ```c
int get_keyword_visual(char *buf) {
  int i, j, ii, len_tmp;
  int flag;
  char para[128];
  i = 0;
  while (buf[i] == ' ')
    i++;
  if (buf[i] != '!')
    HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0002: The control parameter format error: should "
                         "start from !");
  i = i + 1;
  j = 0;
  while ((buf[i] != ' ') && (buf[i] != ',') && (buf[i] != '\n')) {
    para[j] = buf[i];
    i++;
    j++;
  }
  flag = 0;
  para[j] = '\0';
  len_tmp = strlen(para);
  for (ii = 0; ii < len_tmp; ii++) {
    para[ii] = tolower(para[ii]);
  }
  if ((strncmp(para, "VISUAL", 6) != 0) && (strncmp(para, "visual", 6) != 0)) {
    flag = 0;
    return (flag);
  }
  while ((buf[i] != '=') && (buf[i] != '\n'))
    i++;
  if (buf[i] == '\n')
    HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0006:The control parameter format error: visual "
                         "ID");
  i++;
  while ((buf[i] == ' ') && (buf[i] != '\n'))
    i++;
  if (buf[i] == '\n')
    HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0006:The control parameter format error: visual "
                         "ID");
  j = 0;
  while ((buf[i] != ' ') && (buf[i] != ',') && (buf[i] != '=') && (buf[i] != '\n')) {
    para[j] = buf[i];
    i++;
    j++;
  }
  para[j] = '\0';
  len_tmp = strlen(para);
  for (ii = 0; ii < len_tmp; ii++) {
    para[ii] = tolower(para[ii]);
  }
  if ((strncmp(para, "PSR", 3) == 0) || (strncmp(para, "psr", 3) == 0)) {
    flag = 1;
    return (flag);
  }
  if ((strncmp(para, "PVR", 3) == 0) || (strncmp(para, "pvr", 3) == 0)) {
    flag = 2;
    return (flag);
  }
  HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0007:The control parameter format error: method only "
                       "can be PSR or PVR");
  return (flag);
}
```