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

```asm
<getconfstring>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %ecx,-0x2c(%rbp)
  mov    %r8,-0x38(%rbp)
  mov    %r9,-0x40(%rbp)
  mov    -0x28(%rbp),%rdx
  mov    -0x20(%rbp),%rsi
  mov    -0x18(%rbp),%rax
  mov    $0x0,%ecx
  mov    %rax,%rdi
  call   <get_key_value@plt>
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  jne    L112
  cmpl   $0x0,-0x2c(%rbp)
  jne    L112
  mov    -0x28(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  lea    D27(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x1,%edi
  call   <exit@plt>
  jmp    L29
L112:
  cmpq   $0x0,-0x8(%rbp)
  jne    L195
  cmpl   $0x0,-0x2c(%rbp)
  je     L195
  cmpq   $0x0,-0x38(%rbp)
  je     L142
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  jmp    L79
L142:
  mov    -0x38(%rbp),%rax
  jmp    L29
L195:
  nop
L79:
  cmpl   $0x0,0x18(%rbp)
  jne    L171
  mov    -0x8(%rbp),%rax
  mov    %rax,%rdi
  call   <xstrdup@plt>
  jmp    L29
L171:
  movl   $0x0,-0xc(%rbp)
  jmp    L58
L123:
  mov    -0xc(%rbp),%eax
  cltq
  lea    0x0(,%rax,8),%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%rdx
  mov    -0x8(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcasecmp@plt>
  test   %rax,%rax
  je     L115
  addl   $0x1,-0xc(%rbp)
L58:
  mov    -0xc(%rbp),%eax
  cmp    0x18(%rbp),%eax
  jl     L123
  jmp    L211
L115:
  nop
L211:
  mov    -0xc(%rbp),%eax
  cmp    0x18(%rbp),%eax
  jne    L41
  mov    -0x28(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  mov    %rax,%rsi
  lea    D3(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    $0x1,%edi
  call   <exit@plt>
L41:
  cmpq   $0x0,0x10(%rbp)
  je     L62
  cmpq   $0x0,0x20(%rbp)
  je     L62
  mov    -0xc(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rdx
  mov    0x10(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%edx
  mov    0x20(%rbp),%rax
  mov    %edx,(%rax)
  mov    $0x0,%eax
  jmp    L29
L62:
  cmpq   $0x0,0x10(%rbp)
  je     L81
  cmpq   $0x0,0x20(%rbp)
  jne    L81
  lea    D2(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  mov    $0x1,%edi
  call   <exit@plt>
  jmp    L29
L81:
  mov    -0x8(%rbp),%rax
  mov    %rax,%rdi
  call   <xstrdup@plt>
  jmp    L29
L29:
  leave
  ret
```

tool_calls: name: disassemble_data
arguments: data_tag: D27
data_type: string
name: disassemble_data
arguments: data_tag: D3
data_type: string
name: disassemble_data
arguments: data_tag: D2
data_type: string

tool: D27: Config Item: [%s] %s: not set


tool: D3: Config Item: [%s] %s: set error


tool: D2: return value variable pointer isn't set.

assistant: ```c
char *getconfstring(void *cfgdata, const char *section, const char *key, int isnull, char *notfound, char **values, int *ivalues, int valnum, int *retival) {
  const char *cp;
  int i;
  cp = get_key_value(cfgdata, section, key, NULL);
  if (!cp && !isnull) {
    printf("Config Item: [%s] %s: not set\n", section, key);
    exit(1);
  } else if (!cp && isnull) {
    if (notfound) {
      cp = notfound;
      goto process;
    } else
      return notfound;
  } else {
  process:
    if (valnum == 0)
      return xstrdup(cp);
    for (i = 0; i < valnum; ++i) {
      if (strcasecmp(cp, values[i]) == 0)
        break;
    }
    if (i == valnum) {
      printf("Config Item: [%s] %s: set error\n", section, key);
      exit(1);
    }
    if (ivalues && retival) {
      *retival = ivalues[i];
      return NULL;
    } else if (ivalues && !retival) {
      printf("return value variable pointer isn't set.\n");
      exit(1);
    } else
      return xstrdup(cp);
  }
}
```