user: Translate the below assembly code into C programming language:

```asm
<get_cpu_str>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movq   $0x0,-0x50(%rbp)
  movq   $0x0,-0x48(%rbp)
  movl   $0x0,-0x58(%rbp)
  movq   $0x0,-0x40(%rbp)
  lea    D54(%rip),%rax
  mov    %rax,%rsi
  lea    D23(%rip),%rax
  mov    %rax,%rdi
  call   <fopen@plt>
  mov    %rax,-0x38(%rbp)
  cmpq   $0x0,-0x38(%rbp)
  jne    L96
  mov    $0x0,%eax
  jmp    L110
L34:
  mov    -0x50(%rbp),%rax
  lea    -0x30(%rbp),%rdx
  lea    D46(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L8
  addl   $0x1,-0x58(%rbp)
  jmp    L114
L8:
  mov    -0x50(%rbp),%rax
  lea    -0x60(%rbp),%rdx
  lea    D29(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L63
  addl   $0x1,-0x58(%rbp)
  jmp    L114
L63:
  mov    -0x50(%rbp),%rax
  lea    -0x5c(%rbp),%rdx
  lea    D47(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L114
  addl   $0x1,-0x58(%rbp)
L114:
  cmpl   $0x3,-0x58(%rbp)
  jne    L96
  mov    -0x60(%rbp),%esi
  mov    -0x5c(%rbp),%ecx
  lea    -0x30(%rbp),%rdx
  lea    -0x40(%rbp),%rax
  mov    %esi,%r8d
  lea    D27(%rip),%rsi
  mov    %rax,%rdi
  call   <asprintf@plt>
  mov    %eax,-0x54(%rbp)
  cmpl   $0x0,-0x54(%rbp)
  jns    L43
  movq   $0x0,-0x40(%rbp)
  jmp    L43
L96:
  mov    -0x38(%rbp),%rdx
  lea    -0x48(%rbp),%rcx
  lea    -0x50(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <getline@plt>
  test   %rax,%rax
  jg     L34
  jmp    L106
L43:
  nop
L106:
  mov    -0x50(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <fclose@plt>
  mov    -0x40(%rbp),%rax
L110:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L101
  call   <__stack_chk_fail@plt>
L101:
  leave
  ret
```

tool_calls: name: extract_symbolic_data
arguments: tag: D54
type_guessed: string
name: extract_symbolic_data
arguments: tag: D23
type_guessed: string
name: extract_symbolic_data
arguments: tag: D46
type_guessed: string
name: extract_symbolic_data
arguments: tag: D29
type_guessed: string
name: extract_symbolic_data
arguments: tag: D47
type_guessed: string
name: extract_symbolic_data
arguments: tag: D27
type_guessed: string

tool: D54: r

tool: D23: /proc/cpuinfo

tool: D46: vendor_id : %30s

tool: D29: model : %d

tool: D47: cpu family : %d

tool: D27: %s-%d-%X-core

assistant: ```c
char *get_cpu_str(void) {
  char *line = NULL;
  size_t llen = 0;
  int found = 0, n;
  char vendor[30];
  int model, fam;
  char *res = NULL;
  FILE *f = fopen("/proc/cpuinfo", "r");
  if (!f)
    return NULL;
  while (getline(&line, &llen, f) > 0) {
    if (sscanf(line, "vendor_id : %30s", vendor) == 1)
      found++;
    else if (sscanf(line, "model : %d", &model) == 1)
      found++;
    else if (sscanf(line, "cpu family : %d", &fam) == 1)
      found++;
    if (found == 3) {
      n = asprintf(&res, "%s-%d-%X-core", vendor, fam, model);
      if (n < 0)
        res = NULL;
      break;
    }
  }
  free(line);
  fclose(f);
  return res;
}
```