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

```asm
<proc_gps_input>:
  endbr64
  push   %r15
  mov    %edi,%r15d
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x1e8,%rsp
  mov    %r8,0x10(%rsp)
  mov    0x220(%rsp),%r12
  mov    %r9,0x18(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x1d8(%rsp)
  xor    %eax,%eax
  test   %edi,%edi
  jle    L163
  mov    (%rsi),%edx
  mov    %rsi,%r14
  mov    %rcx,%rbx
  xor    %r15d,%r15d
  add    %edi,%edx
  nopw   0x0(%rax,%rax,1)
L9:
  mov    %edx,(%r14)
  mov    $0xa,%esi
  mov    %rbx,%rdi
  call   <memchr@plt>
  mov    %rax,%r13
  test   %rax,%rax
  je     L66
  mov    %r13,%rbp
  mov    %rbx,%rsi
  mov    %r12,%rdi
  sub    %rbx,%rbp
  lea    0x1(%rbp),%edx
  call   <memcpy@plt>
  movb   $0x0,0x0(%r13)
  mov    $0x6,%edx
  mov    %rbx,%rdi
  lea    D79(%rip),%rsi
  call   <strncmp@plt>
  test   %rax,%rax
  je     L162
L285:
  lea    0x1(%r15,%rbp,1),%r15d
  lea    0x1(%r12,%rbp,1),%r12
L1:
  lea    0x1(%r13),%rsi
  movb   $0xa,0x0(%r13)
  mov    (%r14),%eax
  mov    %rsi,%rbp
  sub    %rbx,%rbp
  mov    %ebp,%edx
  cmp    %ebp,%eax
  je     L5
  sub    %ebp,%eax
  mov    %rbx,%rdi
  mov    %eax,%edx
  call   <memmove@plt>
  mov    (%r14),%edx
L5:
  sub    %ebp,%edx
  jmp    L9
  xchg   %ax,%ax
L162:
  lea    0xd0(%rsp),%rdi
  mov    %rbx,%rsi
  mov    %rdi,(%rsp)
  call   <strcpy@plt>
  lea    0x50(%rsp),%rax
  mov    (%rsp),%rdi
  mov    $0xd,%ecx
  lea    D8(%rip),%rdx
  mov    %rax,%rsi
  mov    %rax,0x8(%rsp)
  call   <my_split@plt>
  mov    %eax,(%rsp)
  sub    $0xc,%eax
  cmp    $0x1,%eax
  ja     L285
  lea    0x48(%rsp),%rdi
  call   <compass_get_heading@plt>
  test   %rax,%rax
  jne    L11
  movb   $0x0,0xbc(%rsp)
  lea    0xbc(%rsp),%rbp
L170:
  lea    0x4c(%rsp),%rdi
  call   <tacho_get_speed@plt>
  test   %rax,%rax
  jne    L268
  movb   $0x0,0xc6(%rsp)
L259:
  mov    (%rsp),%eax
  mov    $0x2a,%esi
  sub    $0x1,%eax
  cltq
  mov    0x50(%rsp,%rax,8),%rdi
  call   <strchr@plt>
  mov    %rax,0x20(%rsp)
  mov    %rax,%rdi
  test   %rax,%rax
  je     L167
  call   <strlen@plt>
  cmp    $0x2,%eax
  jg     L271
L167:
  cmpb   $0x0,0xc6(%rsp)
  mov    %rbp,0x90(%rsp)
  je     L7
  lea    0xc6(%rsp),%rdi
  mov    %rdi,0x88(%rsp)
L7:
  xor    %edx,%edx
  mov    %rbx,0x20(%rsp)
  mov    0x8(%rsp),%rbp
  mov    (%rsp),%ebx
  mov    %r13,0x8(%rsp)
  mov    %r12,%r13
  mov    %edx,%r12d
  jmp    L166
  nop
L8:
  movb   $0x2c,0x0(%r13)
  add    $0x1,%r13
  add    $0x1,%r15d
  mov    %r13,%rdi
  call   <strcpy@plt>
  mov    0x0(%rbp),%rdi
  call   <strlen@plt>
  mov    0x0(%rbp),%rdi
  add    %eax,%r15d
  call   <strlen@plt>
  cltq
  add    %rax,%r13
  cmp    %r12d,%ebx
  jle    L270
L184:
  add    $0x8,%rbp
L166:
  add    $0x1,%r12d
  mov    0x0(%rbp),%rsi
  cmp    $0x1,%r12d
  jne    L8
  mov    %r13,%rdi
  call   <strcpy@plt>
  mov    0x0(%rbp),%rdi
  call   <strlen@plt>
  mov    0x0(%rbp),%rdi
  add    %eax,%r15d
  call   <strlen@plt>
  cltq
  add    %rax,%r13
  jmp    L184
  xchg   %ax,%ax
L163:
  lea    D64(%rip),%rdi
  call   <perror@plt>
  nopl   0x0(%rax)
L66:
  mov    0x1d8(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L206
  add    $0x1e8,%rsp
  mov    %r15d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax)
L11:
  cvttss2si 0x48(%rsp),%ecx
  lea    0xbc(%rsp),%rbp
  mov    $0xa,%esi
  lea    D37(%rip),%rdx
  mov    %rbp,%rdi
  call   <snprintf@plt>
  jmp    L170
  nopw   0x0(%rax,%rax,1)
L270:
  mov    %r13,%r12
  mov    0x78(%rsp),%rdi
  mov    0x20(%rsp),%rbx
  add    $0x1,%r15d
  movb   $0xa,(%r12)
  mov    0x8(%rsp),%r13
  add    $0x1,%r12
  call   <to_seconds@plt>
  mov    0x68(%rsp),%rdi
  movsd  %xmm0,(%rsp)
  call   <to_seconds@plt>
  mov    0x70(%rsp),%rax
  movsd  (%rsp),%xmm2
  movapd %xmm0,%xmm1
  cmpb   $0x53,(%rax)
  jne    L12
  xorpd  D34(%rip),%xmm1
L12:
  mov    0x80(%rsp),%rax
  cmpb   $0x57,(%rax)
  jne    L45
  xorpd  D34(%rip),%xmm2
L45:
  mov    0x18(%rsp),%rdx
  mov    0x58(%rsp),%rdi
  movapd %xmm2,%xmm0
  mov    0x98(%rsp),%rsi
  mov    0x10(%rsp),%rax
  call   *%rax
  jmp    L1
  nopl   (%rax)
L268:
  cvttss2si 0x4c(%rsp),%ecx
  lea    0xc6(%rsp),%rdi
  mov    $0xa,%esi
  lea    D37(%rip),%rdx
  call   <snprintf@plt>
  jmp    L259
L271:
  mov    0x20(%rsp),%rax
  mov    $0x10,%edx
  xor    %esi,%esi
  lea    0x1(%rax),%rdi
  call   <strtoul@plt>
  xor    %edx,%edx
  mov    %r13,0x28(%rsp)
  mov    0x90(%rsp),%rdi
  mov    %rbx,0x30(%rsp)
  mov    %eax,%r13d
  mov    %rdx,%rbx
  jmp    L186
  nopl   (%rax)
L313:
  mov    0x90(%rsp),%rdi
  movsbl (%rdi,%rbx,1),%eax
  add    $0x1,%rbx
  xor    %eax,%r13d
L186:
  call   <strlen@plt>
  cmp    %ebx,%eax
  jg     L313
  mov    0x30(%rsp),%rbx
  mov    %r13d,%eax
  xor    %edx,%edx
  mov    %r12,0x30(%rsp)
  mov    0x28(%rsp),%r13
  mov    %rbp,%r12
  mov    %rdx,%rbp
  mov    %rbx,0x28(%rsp)
  mov    %eax,%ebx
  jmp    L219
  nop
L104:
  movsbl (%r12,%rbp,1),%eax
  add    $0x1,%rbp
  xor    %eax,%ebx
L219:
  mov    %r12,%rdi
  call   <strlen@plt>
  cmp    %ebp,%eax
  jg     L104
  cmpb   $0x0,0xc6(%rsp)
  mov    %ebx,%eax
  mov    %r12,%rbp
  mov    0x28(%rsp),%rbx
  mov    0x30(%rsp),%r12
  jne    L317
L121:
  movzbl %al,%ecx
  lea    0xb9(%rsp),%rdi
  mov    $0x3,%esi
  lea    D60(%rip),%rdx
  call   <snprintf@plt>
  movzbl 0xb9(%rsp),%eax
  mov    0x20(%rsp),%rcx
  mov    %al,0x1(%rcx)
  movzbl 0xba(%rsp),%eax
  mov    %al,0x2(%rcx)
  jmp    L167
L317:
  xor    %edx,%edx
  mov    %r13,0x28(%rsp)
  mov    0x88(%rsp),%rdi
  mov    %eax,%r13d
  mov    %rbx,0x30(%rsp)
  mov    %rdx,%rbx
  jmp    L74
L79:
  mov    0x88(%rsp),%rdi
  movsbl (%rdi,%rbx,1),%eax
  add    $0x1,%rbx
  xor    %eax,%r13d
L74:
  call   <strlen@plt>
  cmp    %ebx,%eax
  jg     L79
  xor    %edx,%edx
  lea    0xc6(%rsp),%rdi
  mov    %rbp,0x38(%rsp)
  mov    %rdx,%rbx
  mov    %rdi,%rbp
  jmp    L298
L244:
  movsbl 0x0(%rbp,%rbx,1),%eax
  add    $0x1,%rbx
  xor    %eax,%r13d
L298:
  mov    %rbp,%rdi
  call   <strlen@plt>
  cmp    %ebx,%eax
  jg     L244
  mov    %r13d,%eax
  mov    0x30(%rsp),%rbx
  mov    0x28(%rsp),%r13
  mov    0x38(%rsp),%rbp
  jmp    L121
L206:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: label: D79
type_infered: string
name: unpack_data
arguments: label: D8
type_infered: string
name: unpack_data
arguments: label: D64
type_infered: string
name: unpack_data
arguments: label: D37
type_infered: string
name: unpack_data
arguments: label: D34
type_infered: byte[16]
name: unpack_data
arguments: label: D60
type_infered: string

tool: D79: $GPRMC

tool: D8: ,

tool: D64: proc_gps_input: 

tool: D37: %.1f

tool: {"D34": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]}

tool: D60: %02X

assistant: ```c
int proc_gps_input(int l, int *bufpos, int buflen, char *buf, void (*gpsproc)(char *ptime, char *date, double longg, double latt, void *), void *data, char *writeptr) {
  char *endp;
  int wlen = 0;
  if (l <= 0) {
    perror("proc_gps_input: ");
    return l;
  }
  (*bufpos) += l;
  while ((endp = memchr(buf, '\n', *bufpos))) {
    int readlen;
    memcpy(writeptr, buf, endp - buf + 1);
    *endp = 0;
    if (strncmp(buf, "$GPRMC", 6) == 0) {
      char linebuf[256];
      char *fields[13];
      char headingbuf[10];
      char speedbuf[10];
      strcpy(linebuf, buf);
      int numfields = my_split(linebuf, fields, ",", 13);
      if ((numfields == 12) || (numfields == 13)) {
        double lattsec;
        double longsec;
        float heading;
        float speed;
        if (compass_get_heading(&heading)) {
          snprintf(headingbuf, sizeof(headingbuf), "%.1f", heading);
        } else {
          headingbuf[0] = 0;
        }
        if (tacho_get_speed(&speed)) {
          snprintf(speedbuf, sizeof(speedbuf), "%.1f", speed);
        } else {
          speedbuf[0] = 0;
        }
        if (1) {
          int i;
          int chksum;
          char *chkptr;
          if ((chkptr = strchr(fields[numfields - 1], '*'))) {
            if (strlen(chkptr) > 2) {
              char chkbuf[3];
              chksum = strtoul(chkptr + 1, NULL, 16);
              for (i = 0; i < strlen(fields[8]); i++) {
                chksum ^= (fields[8])[i];
              }
              for (i = 0; i < strlen(headingbuf); i++) {
                chksum ^= headingbuf[i];
              }
              if (speedbuf[0] != 0) {
                for (i = 0; i < strlen(fields[7]); i++) {
                  chksum ^= (fields[7])[i];
                }
                for (i = 0; i < strlen(speedbuf); i++) {
                  chksum ^= speedbuf[i];
                }
              }
              snprintf(chkbuf, sizeof(chkbuf), "%02X", 0xff & (int)chksum);
              chkptr[1] = chkbuf[0];
              chkptr[2] = chkbuf[1];
            }
          }
          fields[8] = headingbuf;
          if (speedbuf[0])
            fields[7] = speedbuf;
          for (i = 0; i < numfields; i++) {
            if (i) {
              writeptr[0] = ',';
              wlen++;
              writeptr++;
            }
            strcpy(writeptr, fields[i]);
            wlen += strlen(fields[i]);
            writeptr += strlen(fields[i]);
          }
          *writeptr = '\n';
          writeptr++;
          wlen++;
        } else {
          wlen += (endp - buf) + 1;
          writeptr += (endp - buf) + 1;
        }
        longsec = to_seconds(fields[5]);
        lattsec = to_seconds(fields[3]);
        if ((fields[4])[0] == 'S')
          lattsec = -lattsec;
        if ((fields[6])[0] == 'W')
          longsec = -longsec;
        gpsproc(fields[1], fields[9], longsec, lattsec, data);
      } else {
        wlen += (endp - buf) + 1;
        writeptr += (endp - buf) + 1;
      }
    } else {
      wlen += (endp - buf) + 1;
      writeptr += (endp - buf) + 1;
    }
    *endp = '\n';
    endp++;
    readlen = endp - buf;
    if (readlen != *bufpos)
      memmove(buf, endp, (*bufpos) - readlen);
    (*bufpos) -= readlen;
  }
  return wlen;
}
```