user: 请将以下的汇编代码转换成C语言代码：

```asm
<ffpsvc>:
  endbr64
  mov    (%rcx),%eax
  test   %eax,%eax
  jg     L21
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,%rbx
  mov    %rsi,%r13
  mov    %rdx,%r12
  mov    %rcx,%r14
  movb   $0x0,(%rsi)
  test   %rdx,%rdx
  je     L618
  movb   $0x0,(%rdx)
L618:
  mov    %rbx,%rdi
  call   <strlen@plt>
  mov    %rax,%rbp
  cmpb   $0x48,(%rbx)
  je     L612
L273:
  cmp    $0x8,%rbp
  jbe    L56
  cmpb   $0x43,(%rbx)
  je     L245
L211:
  cmpb   $0x48,(%rbx)
  je     L530
L316:
  cmpb   $0x45,(%rbx)
  je     L500
L503:
  cmpb   $0x43,(%rbx)
  je     L607
L222:
  cmpb   $0x20,(%rbx)
  je     L235
L34:
  cmpb   $0x3d,0x8(%rbx)
  je     L688
L609:
  lea    D20(%rip),%rsi
  mov    %rbx,%rdi
  call   <strcspn@plt>
  mov    %rax,%r15
  lea    0x1(%rax),%rax
  cmp    %r15,%rbp
  je     L398
L457:
  mov    %rax,%r15
  lea    (%rbx,%rax,1),%rdi
  lea    D50(%rip),%rsi
  call   <strspn@plt>
  add    %rax,%r15
  cmp    %rbp,%r15
  je     L31
  lea    (%rbx,%r15,1),%rax
  mov    %rax,(%rsp)
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  je     L450
  cmp    $0x27,%al
  je     L419
  cmp    $0x28,%al
  jne    L102
  lea    D146(%rip),%rsi
  mov    (%rsp),%rdi
  call   <strcspn@plt>
  mov    %rax,%rbp
  mov    (%rsp),%rdi
  call   <strlen@plt>
  cmp    %rbp,%rax
  je     L227
  lea    0x1(%rbp),%rax
  mov    %rax,0x8(%rsp)
  mov    %rax,%rdx
  mov    (%rsp),%rsi
  mov    %r13,%rdi
  call   <strncpy@plt>
  movb   $0x0,0x1(%r13,%rbp,1)
  add    0x8(%rsp),%r15
  jmp    L74
L612:
  mov    $0x9,%edx
  lea    D129(%rip),%rsi
  mov    %rbx,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L273
  lea    D20(%rip),%rsi
  mov    %rbx,%rdi
  call   <strcspn@plt>
  mov    %rax,%r15
  lea    0x1(%rax),%rax
  cmp    %r15,%rbp
  jne    L457
  cmp    $0x8,%r15
  jbe    L406
  test   %r12,%r12
  jne    L262
L406:
  mov    (%r14),%eax
  jmp    L327
L262:
  lea    0x8(%rbx),%rsi
  mov    %r12,%rdi
  call   <strcpy@plt>
  sub    $0x9,%r15d
  js     L406
  movslq %r15d,%rax
L472:
  cmpb   $0x20,(%r12,%rax,1)
  jne    L406
  movb   $0x0,(%r12,%rax,1)
  sub    $0x1,%rax
  test   %eax,%eax
  jns    L472
  jmp    L406
L245:
  mov    $0x8,%edx
  lea    D131(%rip),%rsi
  mov    %rbx,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L211
L269:
  test   %r12,%r12
  je     L56
  lea    0x8(%rbx),%rsi
  mov    %r12,%rdi
  call   <strcpy@plt>
  sub    $0x9,%ebp
  js     L56
  movslq %ebp,%rbp
L332:
  cmpb   $0x20,(%r12,%rbp,1)
  jne    L56
  movb   $0x0,(%r12,%rbp,1)
  sub    $0x1,%rbp
  test   %ebp,%ebp
  jns    L332
L56:
  mov    (%r14),%eax
L327:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L530:
  mov    $0x8,%edx
  lea    D117(%rip),%rsi
  mov    %rbx,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L316
  jmp    L269
L500:
  mov    $0x8,%edx
  lea    D36(%rip),%rsi
  mov    %rbx,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L503
  jmp    L269
L607:
  mov    $0x8,%edx
  lea    D13(%rip),%rsi
  mov    %rbx,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L222
  jmp    L269
L235:
  mov    $0x8,%edx
  lea    D126(%rip),%rsi
  mov    %rbx,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L34
  jmp    L269
L688:
  lea    0x8(%rbx),%rdi
  mov    $0x2,%edx
  lea    D73(%rip),%rsi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L609
  mov    $0xa,%eax
  jmp    L457
L398:
  test   %r12,%r12
  je     L215
  lea    0x8(%rbx),%rsi
  mov    %r12,%rdi
  call   <strcpy@plt>
  sub    $0x9,%r15d
  js     L215
  movslq %r15d,%r15
L443:
  cmpb   $0x20,(%r12,%r15,1)
  jne    L215
  movb   $0x0,(%r12,%r15,1)
  sub    $0x1,%r15
  test   %r15d,%r15d
  jns    L443
L215:
  mov    (%r14),%eax
  jmp    L327
L31:
  mov    (%r14),%eax
  jmp    L327
L450:
  add    $0x1,%r15
L74:
  test   %r12,%r12
  je     L118
  lea    (%rbx,%r15,1),%rdi
  lea    D50(%rip),%rsi
  call   <strspn@plt>
  lea    (%r15,%rax,1),%rbp
  cmp    $0x4f,%rbp
  ja     L118
  cmpb   $0x2f,(%rbx,%rbp,1)
  je     L132
L504:
  lea    (%rbx,%rbp,1),%rsi
  mov    %r12,%rdi
  call   <strcat@plt>
  mov    %r12,%rdi
  call   <strlen@plt>
  mov    %rax,%rcx
  mov    %eax,%edx
  sub    $0x1,%edx
  js     L118
  movslq %edx,%rdx
  add    %r12,%rdx
  cltq
  lea    -0x2(%r12,%rax,1),%rax
  lea    -0x1(%rcx),%ecx
  sub    %rcx,%rax
L654:
  cmpb   $0x20,(%rdx)
  jne    L118
  movb   $0x0,(%rdx)
  sub    $0x1,%rdx
  cmp    %rax,%rdx
  jne    L654
L118:
  mov    (%r14),%eax
  jmp    L327
L419:
  movb   $0x27,0x0(%r13)
  add    $0x1,%r15
  cmp    %r15,%rbp
  jbe    L378
  mov    $0x1,%eax
  jmp    L610
L8:
  movslq %eax,%rdx
  movb   $0x27,0x0(%r13,%rdx,1)
L276:
  cmp    %r15,%rbp
  je     L143
  cltq
  movb   $0x0,0x1(%r13,%rax,1)
  add    $0x1,%r15
  jmp    L74
L300:
  movzbl (%rbx,%r15,1),%ecx
  movslq %eax,%rdx
  mov    %cl,0x0(%r13,%rdx,1)
  add    $0x1,%r15
  add    $0x1,%eax
  cmp    %r15,%rbp
  jbe    L276
L610:
  cmpb   $0x27,(%rbx,%r15,1)
  jne    L300
  lea    0x1(%r15),%rdx
  cmpb   $0x27,0x1(%rbx,%r15,1)
  jne    L8
  movslq %eax,%rcx
  movb   $0x27,0x0(%r13,%rcx,1)
  add    $0x1,%eax
  mov    %rdx,%r15
  jmp    L300
L378:
  mov    $0x1,%eax
  jmp    L276
L143:
  mov    $0x45,%edx
  cmp    %edx,%eax
  cmovg  %edx,%eax
  cltq
  movb   $0x27,0x0(%r13,%rax,1)
  movb   $0x0,0x1(%r13,%rax,1)
  lea    D149(%rip),%rdi
  call   <ffpmsg@plt>
  mov    %rbx,%rdi
  call   <ffpmsg@plt>
  jmp    L74
L227:
  lea    D1(%rip),%rdi
  call   <ffpmsg@plt>
  mov    %rbx,%rdi
  call   <ffpmsg@plt>
  movl   $0xcd,(%r14)
  mov    $0xcd,%eax
  jmp    L327
L102:
  lea    D34(%rip),%rsi
  mov    (%rsp),%rdi
  call   <strcspn@plt>
  mov    %rax,%rbp
  mov    %rax,%rdx
  mov    (%rsp),%rsi
  mov    %r13,%rdi
  call   <strncpy@plt>
  movb   $0x0,0x0(%r13,%rbp,1)
  add    %rbp,%r15
  jmp    L74
L132:
  lea    0x1(%rbp),%rax
  cmpb   $0x20,0x1(%rbx,%rbp,1)
  je     L11
  mov    %rax,%rbp
  jmp    L504
L11:
  add    $0x2,%rbp
  jmp    L504
L21:
  ret
```

tool_calls: name: retrieve_data
arguments: data_label: D20
type: string
name: retrieve_data
arguments: data_label: D50
type: string
name: retrieve_data
arguments: data_label: D146
type: string
name: retrieve_data
arguments: data_label: D129
type: string
name: retrieve_data
arguments: data_label: D131
type: string
name: retrieve_data
arguments: data_label: D117
type: string
name: retrieve_data
arguments: data_label: D36
type: string
name: retrieve_data
arguments: data_label: D13
type: string
name: retrieve_data
arguments: data_label: D126
type: string
name: retrieve_data
arguments: data_label: D73
type: string
name: retrieve_data
arguments: data_label: D149
type: string
name: retrieve_data
arguments: data_label: D1
type: string
name: retrieve_data
arguments: data_label: D34
type: string

tool: D20: =

tool: D50:  

tool: D146: )

tool: D129: HIERARCH 

tool: D131: COMMENT 

tool: D117: HISTORY 

tool: D36: END     

tool: D13: CONTINUE

tool: D126:         

tool: D73: = 

tool: D149: This keyword string value has no closing quote:

tool: D1: This complex keyword value has no closing ')':

tool: D34:  /

assistant: ```c
int ffpsvc(char *card, char *value, char *comm, int *status) {
  int jj;
  size_t ii, cardlen, nblank, valpos;
  if (*status > 0)
    return (*status);
  value[0] = '\0';
  if (comm)
    comm[0] = '\0';
  cardlen = strlen(card);
  if (((card)[0] < ("HIERARCH ")[0] ? -1 : (card)[0] > ("HIERARCH ")[0] ? 1 : strncmp((card), ("HIERARCH "), (9))) == 0) {
    valpos = strcspn(card, "=");
    if (valpos == cardlen) {
      if (comm != NULL) {
        if (cardlen > 8) {
          strcpy(comm, &card[8]);
          jj = cardlen - 8;
          for (jj--; jj >= 0; jj--) {
            if (comm[jj] == ' ')
              comm[jj] = '\0';
            else
              break;
          }
        }
      }
      return (*status);
    }
    valpos++;
  } else if (cardlen < 9 || ((card)[0] < ("COMMENT ")[0] ? -1 : (card)[0] > ("COMMENT ")[0] ? 1 : strncmp((card), ("COMMENT "), (8))) == 0 || ((card)[0] < ("HISTORY ")[0] ? -1 : (card)[0] > ("HISTORY ")[0] ? 1 : strncmp((card), ("HISTORY "), (8))) == 0 || ((card)[0] < ("END     ")[0] ? -1 : (card)[0] > ("END     ")[0] ? 1 : strncmp((card), ("END     "), (8))) == 0 || ((card)[0] < ("CONTINUE")[0] ? -1 : (card)[0] > ("CONTINUE")[0] ? 1 : strncmp((card), ("CONTINUE"), (8))) == 0 || ((card)[0] < ("        ")[0] ? -1 : (card)[0] > ("        ")[0] ? 1 : strncmp((card), ("        "), (8))) == 0) {
    if (comm != NULL) {
      if (cardlen > 8) {
        strcpy(comm, &card[8]);
        jj = cardlen - 8;
        for (jj--; jj >= 0; jj--) {
          if (comm[jj] == ' ')
            comm[jj] = '\0';
          else
            break;
        }
      }
    }
    return (*status);
  } else if (((&card[8])[0] < ("= ")[0] ? -1 : (&card[8])[0] > ("= ")[0] ? 1 : strncmp((&card[8]), ("= "), (2))) == 0) {
    valpos = 10;
  } else {
    valpos = strcspn(card, "=");
    if (valpos == cardlen) {
      if (comm != NULL) {
        if (cardlen > 8) {
          strcpy(comm, &card[8]);
          jj = cardlen - 8;
          for (jj--; jj >= 0; jj--) {
            if (comm[jj] == ' ')
              comm[jj] = '\0';
            else
              break;
          }
        }
      }
      return (*status);
    }
    valpos++;
  }
  nblank = strspn(&card[valpos], " ");
  if (nblank + valpos == cardlen) {
    return (*status);
  }
  ii = valpos + nblank;
  if (card[ii] == '/') {
    ii++;
  } else if (card[ii] == '\'') {
    value[0] = card[ii];
    for (jj = 1, ii++; ii < cardlen; ii++, jj++) {
      if (card[ii] == '\'') {
        if (card[ii + 1] == '\'') {
          value[jj] = card[ii];
          ii++;
          jj++;
        } else {
          value[jj] = card[ii];
          break;
        }
      }
      value[jj] = card[ii];
    }
    if (ii == cardlen) {
      jj = ((jj) < (69) ? (jj) : (69));
      value[jj] = '\'';
      value[jj + 1] = '\0';
      ffpmsg("This keyword string value has no closing quote:");
      ffpmsg(card);
    } else {
      value[jj + 1] = '\0';
      ii++;
    }
  } else if (card[ii] == '(') {
    nblank = strcspn(&card[ii], ")");
    if (nblank == strlen(&card[ii])) {
      ffpmsg("This complex keyword value has no closing ')':");
      ffpmsg(card);
      return (*status = 205);
    }
    nblank++;
    strncpy(value, &card[ii], nblank);
    value[nblank] = '\0';
    ii = ii + nblank;
  } else {
    nblank = strcspn(&card[ii], " /");
    strncpy(value, &card[ii], nblank);
    value[nblank] = '\0';
    ii = ii + nblank;
  }
  if (comm) {
    nblank = strspn(&card[ii], " ");
    ii = ii + nblank;
    if (ii < 80) {
      if (card[ii] == '/') {
        ii++;
        if (card[ii] == ' ')
          ii++;
      }
      strcat(comm, &card[ii]);
      jj = strlen(comm);
      for (jj--; jj >= 0; jj--) {
        if (comm[jj] == ' ')
          comm[jj] = '\0';
        else
          break;
      }
    }
  }
  return (*status);
}
```