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

```asm
<get_fps>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x840,%rsp
  mov    %rdi,-0x838(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movsd  D90(%rip),%xmm0
  movsd  %xmm0,-0x828(%rbp)
  lea    D86(%rip),%rax
  mov    %rax,%rdi
  call   <system@plt>
  mov    %eax,-0x82c(%rbp)
  cmpl   $0x0,-0x82c(%rbp)
  jne    L17
  lea    D80(%rip),%rax
  mov    %rax,-0x820(%rbp)
  jmp    L33
L17:
  lea    D35(%rip),%rax
  mov    %rax,%rdi
  call   <system@plt>
  mov    %eax,-0x82c(%rbp)
  cmpl   $0x0,-0x82c(%rbp)
  jne    L37
  lea    D69(%rip),%rax
  mov    %rax,-0x820(%rbp)
  jmp    L33
L37:
  lea    D76(%rip),%rax
  mov    %rax,%rdi
  call   <system@plt>
  mov    %eax,-0x82c(%rbp)
  cmpl   $0x0,-0x82c(%rbp)
  jne    L21
  lea    D62(%rip),%rax
  mov    %rax,-0x820(%rbp)
  nop
L33:
  mov    -0x838(%rbp),%rcx
  mov    -0x820(%rbp),%rdx
  lea    -0x410(%rbp),%rax
  mov    %rcx,%r8
  mov    %rdx,%rcx
  lea    D40(%rip),%rdx
  mov    $0x400,%esi
  mov    %rax,%rdi
  call   <snprintf@plt>
  lea    -0x410(%rbp),%rax
  lea    D28(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <popen@plt>
  mov    %rax,-0x818(%rbp)
  mov    -0x818(%rbp),%rdx
  lea    -0x810(%rbp),%rax
  mov    $0x400,%esi
  mov    %rax,%rdi
  call   <fgets@plt>
  lea    -0x810(%rbp),%rax
  mov    $0xd,%edx
  lea    D79(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L20
  lea    -0x810(%rbp),%rax
  add    $0xd,%rax
  mov    $0x0,%esi
  mov    %rax,%rdi
  call   <strtod@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x828(%rbp)
L20:
  mov    -0x818(%rbp),%rax
  mov    %rax,%rdi
  call   <pclose@plt>
  jmp    L14
L21:
  nop
L14:
  movsd  -0x828(%rbp),%xmm0
  movq   %xmm0,%rax
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L74
  call   <__stack_chk_fail@plt>
L74:
  movq   %rax,%xmm0
  leave
  ret
```

tool_calls: name: extract_symbolic_data
arguments: data_tag: D90
datatype: byte[8]
name: extract_symbolic_data
arguments: data_tag: D86
datatype: string
name: extract_symbolic_data
arguments: data_tag: D80
datatype: string
name: extract_symbolic_data
arguments: data_tag: D35
datatype: string
name: extract_symbolic_data
arguments: data_tag: D69
datatype: string
name: extract_symbolic_data
arguments: data_tag: D76
datatype: string
name: extract_symbolic_data
arguments: data_tag: D62
datatype: string
name: extract_symbolic_data
arguments: data_tag: D40
datatype: string
name: extract_symbolic_data
arguments: data_tag: D28
datatype: string
name: extract_symbolic_data
arguments: data_tag: D79
datatype: string

tool: {"D90": [0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xbf]}

tool: D86: which mplayer2

tool: D80: mplayer2

tool: D35: which mplayer

tool: D69: mplayer

tool: D76: which mpv

tool: D62: mpv

tool: D40: LANGUAGE=en LANG=en %s "%s" -identify -frames 0 2>/dev/null | grep ID_VIDEO_FPS

tool: D28: r

tool: D79: ID_VIDEO_FPS=

assistant: ```c
double get_fps(const char *uri) {
  int rc;
  double ret = -1;
  const char *binary;
  char buffer[1024];
  char cmd[1024];
  ssize_t bytes;
  FILE *fp;
  rc = system("which "
              "mplayer2");
  if (rc == 0) {
    binary = "mplayer2";
    goto found_player;
  }
  rc = system("which "
              "mplayer");
  if (rc == 0) {
    binary = "mplayer";
    goto found_player;
  }
  rc = system("which "
              "mpv");
  if (rc == 0) {
    binary = "mpv";
    goto found_player;
  }
  goto exit;
found_player:
  snprintf(cmd, 1024, "LANGUAGE=en LANG=en %s \"%s\" -identify -frames 0 2>/dev/null | grep ID_VIDEO_FPS", binary, uri);
  fp = popen(cmd, "r");
  fgets(buffer, 1024, fp);
  if (!(strncmp(buffer, "ID_VIDEO_FPS=", 13))) {
    ret = strtod(buffer + 13, NULL);
  }
  pclose(fp);
exit:
  return ret;
}
```