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

```asm
<PS2_FormatMemoryUnit>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0xa0,%rsp
  mov    %edi,-0x94(%rbp)
  mov    %esi,-0x98(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  cmpl   $0x3ff,-0x94(%rbp)
  ja     L207
  cmpl   $0x0,-0x98(%rbp)
  je     L75
  lea    D97(%rip),%rax
  jmp    L130
L75:
  lea    D103(%rip),%rax
L130:
  mov    %rax,-0x88(%rbp)
  mov    -0x94(%rbp),%eax
  test   %rax,%rax
  js     L209
  pxor   %xmm0,%xmm0
  cvtsi2ss %rax,%xmm0
  jmp    L157
L209:
  mov    %rax,%rdx
  shr    %rdx
  and    $0x1,%eax
  or     %rax,%rdx
  pxor   %xmm0,%xmm0
  cvtsi2ss %rdx,%xmm0
  addss  %xmm0,%xmm0
L157:
  movss  %xmm0,-0x90(%rbp)
  jmp    L95
L207:
  cmpl   $0xfffff,-0x94(%rbp)
  ja     L16
  cmpl   $0x0,-0x98(%rbp)
  je     L174
  lea    D9(%rip),%rax
  jmp    L173
L174:
  lea    D82(%rip),%rax
L173:
  mov    %rax,-0x88(%rbp)
  mov    -0x94(%rbp),%eax
  test   %rax,%rax
  js     L28
  pxor   %xmm0,%xmm0
  cvtsi2ss %rax,%xmm0
  jmp    L324
L28:
  mov    %rax,%rdx
  shr    %rdx
  and    $0x1,%eax
  or     %rax,%rdx
  pxor   %xmm0,%xmm0
  cvtsi2ss %rdx,%xmm0
  addss  %xmm0,%xmm0
L324:
  movss  D47(%rip),%xmm1
  divss  %xmm1,%xmm0
  movss  %xmm0,-0x90(%rbp)
  jmp    L95
L16:
  cmpl   $0x3fffffff,-0x94(%rbp)
  ja     L94
  cmpl   $0x0,-0x98(%rbp)
  je     L87
  lea    D187(%rip),%rax
  jmp    L213
L87:
  lea    D11(%rip),%rax
L213:
  mov    %rax,-0x88(%rbp)
  mov    -0x94(%rbp),%eax
  test   %rax,%rax
  js     L219
  pxor   %xmm0,%xmm0
  cvtsi2ss %rax,%xmm0
  jmp    L36
L219:
  mov    %rax,%rdx
  shr    %rdx
  and    $0x1,%eax
  or     %rax,%rdx
  pxor   %xmm0,%xmm0
  cvtsi2ss %rdx,%xmm0
  addss  %xmm0,%xmm0
L36:
  movss  D47(%rip),%xmm1
  divss  %xmm1,%xmm0
  movss  D47(%rip),%xmm1
  divss  %xmm1,%xmm0
  movss  %xmm0,-0x90(%rbp)
  jmp    L95
L94:
  cmpl   $0x0,-0x98(%rbp)
  je     L177
  lea    D169(%rip),%rax
  jmp    L329
L177:
  lea    D87(%rip),%rax
L329:
  mov    %rax,-0x88(%rbp)
  mov    -0x94(%rbp),%eax
  test   %rax,%rax
  js     L250
  pxor   %xmm0,%xmm0
  cvtsi2ss %rax,%xmm0
  jmp    L319
L250:
  mov    %rax,%rdx
  shr    %rdx
  and    $0x1,%eax
  or     %rax,%rdx
  pxor   %xmm0,%xmm0
  cvtsi2ss %rdx,%xmm0
  addss  %xmm0,%xmm0
L319:
  movss  D47(%rip),%xmm1
  divss  %xmm1,%xmm0
  movss  D47(%rip),%xmm1
  divss  %xmm1,%xmm0
  movss  D47(%rip),%xmm1
  divss  %xmm1,%xmm0
  movss  %xmm0,-0x90(%rbp)
L95:
  mov    D4(%rip),%eax
  cltq
  shl    $0x7,%rax
  mov    %rax,%rdx
  lea    D78(%rip),%rax
  add    %rdx,%rax
  mov    %rax,-0x78(%rbp)
  mov    D4(%rip),%eax
  add    $0x1,%eax
  and    $0x7,%eax
  mov    %eax,D120(%rip)
  pxor   %xmm2,%xmm2
  cvtss2sd -0x90(%rbp),%xmm2
  movq   %xmm2,%rdx
  lea    -0x70(%rbp),%rax
  movq   %rdx,%xmm0
  lea    D120(%rip),%rdx
  mov    $0x64,%esi
  mov    %rax,%rdi
  mov    $0x1,%eax
  call   <snprintf@plt>
  mov    %eax,-0x8c(%rbp)
  cmpl   $0x0,-0x8c(%rbp)
  jg     L67
  mov    -0x78(%rbp),%rax
  movb   $0x3f,(%rax)
  mov    -0x78(%rbp),%rax
  add    $0x1,%rax
  movb   $0x3f,(%rax)
  mov    -0x78(%rbp),%rax
  add    $0x2,%rax
  movb   $0x3f,(%rax)
  mov    -0x78(%rbp),%rax
  add    $0x3,%rax
  movb   $0x0,(%rax)
  mov    -0x78(%rbp),%rax
  jmp    L66
L67:
  lea    -0x70(%rbp),%rax
  mov    %rax,-0x80(%rbp)
  jmp    L357
L147:
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L164
  nop
L161:
  addq   $0x1,-0x80(%rbp)
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L161
  jmp    L268
L339:
  mov    -0x80(%rbp),%rax
  movb   $0x0,(%rax)
L268:
  subq   $0x1,-0x80(%rbp)
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x30,%al
  je     L339
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L220
  mov    -0x80(%rbp),%rax
  movb   $0x0,(%rax)
  jmp    L220
L164:
  addq   $0x1,-0x80(%rbp)
L357:
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L147
  jmp    L108
L220:
  nop
L108:
  mov    -0x88(%rbp),%rcx
  lea    -0x70(%rbp),%rdx
  mov    -0x78(%rbp),%rax
  mov    %rcx,%r8
  mov    %rdx,%rcx
  lea    D39(%rip),%rdx
  mov    $0x80,%esi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <snprintf@plt>
  mov    %eax,-0x8c(%rbp)
  cmpl   $0x0,-0x8c(%rbp)
  jg     L122
  mov    -0x78(%rbp),%rax
  movb   $0x3f,(%rax)
  mov    -0x78(%rbp),%rax
  add    $0x1,%rax
  movb   $0x3f,(%rax)
  mov    -0x78(%rbp),%rax
  add    $0x2,%rax
  movb   $0x3f,(%rax)
  mov    -0x78(%rbp),%rax
  add    $0x3,%rax
  movb   $0x0,(%rax)
  mov    -0x78(%rbp),%rax
  jmp    L66
L122:
  mov    -0x78(%rbp),%rax
L66:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L253
  call   <__stack_chk_fail@plt>
L253:
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: data_tag: D97
type_infered: string
name: retrieve_data
arguments: data_tag: D103
type_infered: string
name: retrieve_data
arguments: data_tag: D9
type_infered: string
name: retrieve_data
arguments: data_tag: D82
type_infered: string
name: retrieve_data
arguments: data_tag: D47
type_infered: byte[4]
name: retrieve_data
arguments: data_tag: D187
type_infered: string
name: retrieve_data
arguments: data_tag: D11
type_infered: string
name: retrieve_data
arguments: data_tag: D169
type_infered: string
name: retrieve_data
arguments: data_tag: D87
type_infered: string
name: retrieve_data
arguments: data_tag: D120
type_infered: string
name: retrieve_data
arguments: data_tag: D39
type_infered: string

tool: D97: B

tool: D103: Bytes

tool: D9: KB

tool: D82: Kilobytes

tool: {"D47": [0x00,0x00,0x80,0x44]}

tool: D187: MB

tool: D11: Megabytes

tool: D169: GB

tool: D87: Gigabytes

tool: D120: %.2f

tool: D39: %s %s

assistant: ```c
const char *PS2_FormatMemoryUnit(unsigned int size_bytes, int abbreviated) {
  enum { KILOBYTE = 1024, MEGABYTE = 1024 * KILOBYTE, GIGABYTE = 1024 * MEGABYTE };
  const char *mem_unit_str;
  float adjusted_size;
  if (size_bytes < KILOBYTE) {
    mem_unit_str = abbreviated ? "B" : "Bytes";
    adjusted_size = (float)size_bytes;
  } else if (size_bytes < MEGABYTE) {
    mem_unit_str = abbreviated ? "KB" : "Kilobytes";
    adjusted_size = size_bytes / 1024.0f;
  } else if (size_bytes < GIGABYTE) {
    mem_unit_str = abbreviated ? "MB" : "Megabytes";
    adjusted_size = size_bytes / 1024.0f / 1024.0f;
  } else {
    mem_unit_str = abbreviated ? "GB" : "Gigabytes";
    adjusted_size = size_bytes / 1024.0f / 1024.0f / 1024.0f;
  }
  char *fmtbuf;
  int chars_written;
  char num_str_buf[100];
  enum { MEM_UNIT_STR_MAXLEN = sizeof(num_str_buf) + 28 };
  static int bufnum = 0;
  static char local_str_buf[8][MEM_UNIT_STR_MAXLEN];
  fmtbuf = local_str_buf[bufnum];
  bufnum = (bufnum + 1) & 7;
  chars_written = snprintf(num_str_buf, 100, "%.2f", adjusted_size);
  if (chars_written <= 0) {
    fmtbuf[0] = '?';
    fmtbuf[1] = '?';
    fmtbuf[2] = '?';
    fmtbuf[3] = '\0';
    return fmtbuf;
  }
  char *p = num_str_buf;
  for (; *p; ++p) {
    if (*p == '.') {
      while (*++p) {
      }
      while (*--p == '0') {
        *p = '\0';
      }
      if (*p == '.') {
        *p = '\0';
      }
      break;
    }
  }
  chars_written = snprintf(fmtbuf, MEM_UNIT_STR_MAXLEN, "%s %s", num_str_buf, mem_unit_str);
  if (chars_written <= 0) {
    fmtbuf[0] = '?';
    fmtbuf[1] = '?';
    fmtbuf[2] = '?';
    fmtbuf[3] = '\0';
    return fmtbuf;
  }
  return fmtbuf;
}
```