user: Demonstrate the C code that generates the assembly output below:

```asm
<string_format_size>:
  endbr64
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  sub    $0x140,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x138(%rsp)
  lea    D104(%rip),%rax
  movl   $0x44800000,0x4(%rsp)
  movb   $0x0,0xb0(%rsp)
  mov    %rax,0x18(%rsp)
  lea    D100(%rip),%rax
  mov    %rax,0x20(%rsp)
  lea    D94(%rip),%rax
  mov    %rax,0x28(%rsp)
  movabs $0x4e80000049800000,%rax
  mov    %rax,0x8(%rsp)
  cmp    $0x27ff,%rdi
  jbe    L45
  lea    D2(%rip),%rcx
  mov    $0x1,%ebp
  cmp    $0xfffff,%rdi
  ja     L58
L0:
  lea    0x30(%rsp),%r12
  movslq %ebp,%rbp
  mov    $0x80,%esi
  xor    %eax,%eax
  lea    D77(%rip),%rdx
  mov    %r12,%rdi
  call   <snprintf@plt>
  mov    0x10(%rsp,%rbp,8),%rcx
  movss  (%rsp,%rbp,4),%xmm1
  test   %rbx,%rbx
  js     L32
L40:
  pxor   %xmm0,%xmm0
  cvtsi2ss %rbx,%xmm0
L50:
  divss  %xmm1,%xmm0
  lea    0xb0(%rsp),%rbp
  mov    %r12,%rdx
  mov    $0x80,%esi
  mov    %rbp,%rdi
  mov    $0x1,%eax
  cvtss2sd %xmm0,%xmm0
  call   <snprintf@plt>
  mov    %rbp,%rdi
  call   <strdup@plt>
  mov    0x138(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L42
  add    $0x140,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  ret
  cs nopw 0x0(%rax,%rax,1)
L58:
  cmp    $0x40000000,%rdi
  lea    D63(%rip),%rcx
  sbb    %ebp,%ebp
  add    $0x3,%ebp
  jmp    L0
  nopl   0x0(%rax,%rax,1)
L45:
  lea    0x30(%rsp),%r12
  lea    D44(%rip),%rcx
  xor    %eax,%eax
  mov    $0x80,%esi
  lea    D77(%rip),%rdx
  mov    %r12,%rdi
  call   <snprintf@plt>
  cmp    $0x2,%rbx
  lea    D53(%rip),%rcx
  lea    D9(%rip),%rax
  movss  D78(%rip),%xmm1
  cmovae %rax,%rcx
  test   %rbx,%rbx
  jns    L40
L32:
  mov    %rbx,%rax
  pxor   %xmm0,%xmm0
  and    $0x1,%ebx
  shr    %rax
  or     %rbx,%rax
  cvtsi2ss %rax,%xmm0
  addss  %xmm0,%xmm0
  jmp    L50
L42:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: extract_symbolic_data
arguments: data_tag: D104
type: string
name: extract_symbolic_data
arguments: data_tag: D100
type: string
name: extract_symbolic_data
arguments: data_tag: D94
type: string
name: extract_symbolic_data
arguments: data_tag: D2
type: string
name: extract_symbolic_data
arguments: data_tag: D77
type: string
name: extract_symbolic_data
arguments: data_tag: D63
type: string
name: extract_symbolic_data
arguments: data_tag: D44
type: string
name: extract_symbolic_data
arguments: data_tag: D53
type: string
name: extract_symbolic_data
arguments: data_tag: D9
type: string
name: extract_symbolic_data
arguments: data_tag: D78
type: byte[4]

tool: D104: KB

tool: D100: MB

tool: D94: GB

tool: D2: %.1f

tool: D77: %s %%s

tool: D63: %.02f

tool: D44: %.0f

tool: D53: byte

tool: D9: bytes

tool: {"D78": [0x00,0x00,0x80,0x3f]}

assistant: ```c
char *string_format_size(unsigned long size) {
  char *unit_name[] = {("bytes"), ("KB"), ("MB"), ("GB")};
  char *unit_format[] = {"%.0f", "%.1f", "%.02f", "%.02f"};
  float unit_divide[] = {1, 1024, 1024 * 1024, 1024 * 1024 * 1024};
  char format_size[128], str_size[128];
  int num_unit;
  str_size[0] = '\0';
  if (size < 1024 * 10)
    num_unit = 0;
  else if (size < 1024 * 1024)
    num_unit = 1;
  else if (size < 1024 * 1024 * 1024)
    num_unit = 2;
  else
    num_unit = 3;
  snprintf(format_size, sizeof(format_size), "%s %%s", unit_format[num_unit]);
  snprintf(str_size, sizeof(str_size), format_size, ((float)size) / ((float)(unit_divide[num_unit])), (size <= 1) ? ("byte") : (unit_name[num_unit]));
  return strdup(str_size);
}
```