user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<get_key_value>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  movq   $0x0,(%rdx)
  movq   $0x0,(%rsi)
  test   %rdi,%rdi
  je     L318
  mov    %rdi,%r13
  mov    %rsi,%r14
  mov    %rdx,%r15
  movzbl (%rdi),%edi
  mov    %r13,%rbx
  test   %dil,%dil
  je     L309
L36:
  movsbl %dil,%edi
  call   <isspace@plt>
  test   %rax,%rax
  je     L325
  add    $0x1,%rbx
  movzbl (%rbx),%edi
  test   %dil,%dil
  jne    L36
L309:
  mov    $0x0,%eax
  jmp    L168
L318:
  lea    D41(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L325:
  movzbl (%rbx),%edi
  test   %dil,%dil
  je     L159
  cmp    $0x23,%dil
  je     L159
  mov    %rbx,%rbp
  cmp    $0x5b,%dil
  je     L143
L170:
  movsbl %dil,%edi
  call   <isalnum@plt>
  test   %rax,%rax
  je     L266
  add    $0x1,%rbp
  movzbl 0x0(%rbp),%edi
  test   %dil,%dil
  jne    L170
L324:
  mov    %r13,%rsi
  lea    D12(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L143:
  lea    0x1(%rbx),%rbp
  movzbl 0x1(%rbx),%eax
  test   %al,%al
  je     L322
  cmp    $0x5d,%al
  je     L322
  mov    %rbp,%rdx
L157:
  add    $0x1,%rdx
  movzbl (%rdx),%eax
  test   %al,%al
  je     L2
  cmp    $0x5d,%al
  jne    L157
L2:
  cmp    $0x5d,%al
  jne    L175
  movb   $0x0,(%rdx)
  mov    %rbp,%rdi
  call   <strlen@plt>
  mov    $0x5,%edi
  call   <malloc@plt>
  mov    %rax,%rdi
  mov    %rax,(%r14)
  test   %rax,%rax
  je     L232
  mov    %rbp,%rsi
  call   <strcpy@plt>
  mov    $0x0,%eax
  jmp    L168
L322:
  mov    %rbp,%rdx
  jmp    L2
L175:
  mov    %r13,%rsi
  lea    D26(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L232:
  lea    D89(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L266:
  movzbl 0x0(%rbp),%edi
  test   %dil,%dil
  je     L324
  mov    %rbp,%rax
  sub    %rbx,%rax
  mov    %rax,(%rsp)
  mov    %eax,0xc(%rsp)
L140:
  movsbl %dil,%edi
  call   <isspace@plt>
  test   %rax,%rax
  je     L271
  add    $0x1,%rbp
  movzbl 0x0(%rbp),%edi
  test   %dil,%dil
  jne    L140
L155:
  mov    %r13,%rsi
  lea    D12(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L271:
  lea    0x1(%rbp),%r12
  cmpb   $0x3d,0x0(%rbp)
  jne    L155
  movzbl 0x1(%rbp),%edi
  test   %dil,%dil
  je     L156
L24:
  movsbl %dil,%edi
  call   <isspace@plt>
  test   %rax,%rax
  je     L156
  add    $0x1,%r12
  movzbl (%r12),%edi
  test   %dil,%dil
  jne    L24
L156:
  movsbl (%r12),%edi
  call   <isalnum@plt>
  test   %rax,%rax
  je     L485
  movzbl (%r12),%edi
  cmp    $0x23,%dil
  je     L485
  mov    %r12,%rbp
  test   %dil,%dil
  je     L444
L115:
  movsbl %dil,%edi
  call   <isalnum@plt>
  test   %rax,%rax
  je     L387
  cmpb   $0x23,0x0(%rbp)
  je     L185
  add    $0x1,%rbp
  movzbl 0x0(%rbp),%edi
  test   %dil,%dil
  jne    L115
L444:
  mov    %ebp,%eax
  sub    %r12d,%eax
  mov    %eax,0x8(%rsp)
  jmp    L235
L485:
  mov    %r13,%rsi
  lea    D12(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L387:
  mov    %ebp,%eax
  sub    %r12d,%eax
  mov    %eax,0x8(%rsp)
  movzbl 0x0(%rbp),%edi
  test   %dil,%dil
  je     L235
L215:
  movsbl %dil,%edi
  call   <isspace@plt>
  test   %rax,%rax
  je     L395
  add    $0x1,%rbp
  movzbl 0x0(%rbp),%edi
  test   %dil,%dil
  jne    L215
L235:
  mov    (%rsp),%eax
  lea    0x1(%rax),%edi
  call   <malloc@plt>
  mov    %rax,(%r14)
  test   %rax,%rax
  je     L465
  mov    0x8(%rsp),%eax
  lea    0x1(%rax),%edi
  call   <malloc@plt>
  mov    %rax,(%r15)
  test   %rax,%rax
  je     L79
  mov    0xc(%rsp),%edx
  mov    %rbx,%rsi
  mov    (%r14),%rdi
  call   <memcpy@plt>
  mov    0x8(%rsp),%ebx
  mov    %ebx,%edx
  mov    %r12,%rsi
  mov    (%r15),%rdi
  call   <memcpy@plt>
  movslq (%rsp),%rax
  mov    (%r14),%rdx
  movb   $0x0,(%rdx,%rax,1)
  movslq %ebx,%rax
  mov    (%r15),%rdx
  movb   $0x0,(%rdx,%rax,1)
  mov    $0x0,%eax
L168:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L395:
  movzbl 0x0(%rbp),%eax
  test   %al,%al
  je     L235
  cmp    $0x23,%al
  je     L235
  mov    %r13,%rsi
  lea    D12(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L465:
  lea    D72(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L79:
  mov    (%r14),%rdi
  call   <free@plt>
  movq   $0x0,(%r14)
  lea    D29(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L168
L159:
  mov    $0x0,%eax
  jmp    L168
L185:
  mov    %ebp,%eax
  sub    %r12d,%eax
  mov    %eax,0x8(%rsp)
  movzbl 0x0(%rbp),%edi
  jmp    L215
```

tool_calls: name: read_data
arguments: data_tag: D41
type_guessed: string
name: read_data
arguments: data_tag: D12
type_guessed: string
name: read_data
arguments: data_tag: D26
type_guessed: string
name: read_data
arguments: data_tag: D89
type_guessed: string
name: read_data
arguments: data_tag: D72
type_guessed: string
name: read_data
arguments: data_tag: D29
type_guessed: string

tool: D41: buf is null

tool: D12: invalid line[%s]


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


tool: D89: malloc key failed.

tool: D72: malloc ppkey failed.

tool: D29: 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;
}
```