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

```asm
<get_key_value>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x38(%rbp),%rax
  movq   $0x0,(%rax)
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x30(%rbp),%rax
  mov    %rdx,(%rax)
  cmpq   $0x0,-0x18(%rbp)
  jne    L112
  lea    D55(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L213:
  addq   $0x1,-0x18(%rbp)
L112:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L201
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isspace@plt>
  test   %rax,%rax
  jne    L213
L201:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L168
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x23,%al
  jne    L43
L168:
  mov    $0x0,%eax
  jmp    L386
L43:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5b,%al
  jne    L237
  addq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  jmp    L192
L449:
  addq   $0x1,-0x18(%rbp)
L192:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L301
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5d,%al
  jne    L449
L301:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5d,%al
  jne    L333
  mov    -0x18(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %eax,-0x20(%rbp)
  mov    $0x5,%edi
  call   <malloc@plt>
  mov    %rax,%rdx
  mov    -0x30(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  jne    L359
  jmp    L405
L333:
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D63(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L405:
  lea    D11(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L359:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  mov    -0x10(%rbp),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
  mov    $0x0,%eax
  jmp    L386
L237:
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  jmp    L83
L45:
  addq   $0x1,-0x18(%rbp)
L83:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L128
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isalnum@plt>
  test   %rax,%rax
  jne    L45
L128:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L81
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D14(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L81:
  mov    -0x18(%rbp),%rax
  sub    -0x10(%rbp),%rax
  mov    %eax,-0x20(%rbp)
  jmp    L352
L49:
  addq   $0x1,-0x18(%rbp)
L352:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L89
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isspace@plt>
  test   %rax,%rax
  jne    L49
L89:
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  cmp    $0x3d,%al
  je     L38
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D14(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L422:
  addq   $0x1,-0x18(%rbp)
L38:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L294
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isspace@plt>
  test   %rax,%rax
  jne    L422
L294:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isalnum@plt>
  test   %rax,%rax
  je     L14
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x23,%al
  jne    L246
L14:
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D14(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L246:
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  jmp    L141
L404:
  addq   $0x1,-0x18(%rbp)
L141:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L356
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isalnum@plt>
  test   %rax,%rax
  je     L356
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x23,%al
  jne    L404
L356:
  mov    -0x18(%rbp),%rax
  sub    -0x8(%rbp),%rax
  mov    %eax,-0x1c(%rbp)
  jmp    L197
L453:
  addq   $0x1,-0x18(%rbp)
L197:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L415
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isspace@plt>
  test   %rax,%rax
  jne    L453
L415:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L307
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x23,%al
  je     L307
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  lea    D14(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L307:
  mov    -0x20(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,%rdx
  mov    -0x30(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  jne    L262
  lea    D44(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L262:
  mov    -0x1c(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  jne    L409
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x30(%rbp),%rax
  movq   $0x0,(%rax)
  lea    D46(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L386
L409:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  mov    -0x20(%rbp),%edx
  mov    -0x10(%rbp),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rax
  mov    -0x1c(%rbp),%edx
  mov    -0x8(%rbp),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x20(%rbp),%eax
  cltq
  add    %rdx,%rax
  movb   $0x0,(%rax)
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x1c(%rbp),%eax
  cltq
  add    %rdx,%rax
  movb   $0x0,(%rax)
  mov    $0x0,%eax
L386:
  leave
  ret
```

tool_calls: name: unpack_data
arguments: label: D55
type: string
name: unpack_data
arguments: label: D63
type: string
name: unpack_data
arguments: label: D11
type: string
name: unpack_data
arguments: label: D14
type: string
name: unpack_data
arguments: label: D44
type: string
name: unpack_data
arguments: label: D46
type: string

tool: D55: buf is null

tool: D63: invalid line, line[%s]


tool: D11: malloc key failed.

tool: D14: invalid line[%s]


tool: D44: malloc ppkey failed.

tool: D46: malloc ppval failed.

assistant: ```c
int get_key_value(char *buf, char **ppkey, char **ppval) {
  char *saveptr, *key, *value, *line;
  int keylen, vallen;
  line = buf;
  *ppkey = *ppval = NULL;
  if (line == NULL) {
    printf("buf is null\n");
    return -1;
  }
  for (; *line && isspace(*line); line++)
    ;
  if (*line == 0 || *line == '#') {
    return 0;
  }
  if (*line == '[') {
    key = ++line;
    while (*line && *line != ']')
      line++;
    if (*line == ']')
      *line = 0;
    else {
      printf("invalid line, line[%s]\n", buf);
      return -1;
    }
    keylen = strlen(key);
    *ppkey = (char *)malloc(sizeof(keylen) + 1);
    if (*ppkey == NULL) {
      printf("malloc key failed.\n");
      return -1;
    }
    strcpy(*ppkey, key);
    return 0;
  }
  key = line;
  while (*line && isalnum(*line))
    line++;
  if (*line == 0) {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  keylen = line - key;
  while (*line && isspace(*line))
    line++;
  if (*line++ != '=') {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  while (*line && isspace(*line))
    line++;
  if (!isalnum(*line) || *line == '#') {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  value = line;
  while (*line && isalnum(*line) && *line != '#')
    line++;
  vallen = line - value;
  while (*line && isspace(*line))
    line++;
  if (*line != 0 && *line != '#') {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  *ppkey = (char *)malloc(keylen + 1);
  if (*ppkey == NULL) {
    printf("malloc ppkey failed.\n");
    return -1;
  }
  *ppval = (char *)malloc(vallen + 1);
  if (*ppval == NULL) {
    free(*ppkey);
    *ppkey = NULL;
    printf("malloc ppval failed.\n");
    return -1;
  }
  memcpy(*ppkey, key, keylen);
  memcpy(*ppval, value, vallen);
  *(*ppkey + keylen) = 0;
  *(*ppval + vallen) = 0;
  return 0;
}
```