user: 请从给定的汇编指令推导出C源代码：

```asm
<string_format_size>:
  endbr64
  push   %r12
  lea    D60(%rip),%rsi
  push   %rbp
  movq   %rsi,%xmm0
  push   %rbx
  mov    %rdi,%rbx
  sub    $0x140,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x138(%rsp)
  lea    D42(%rip),%rax
  movl   $0x4e800000,0xc(%rsp)
  movb   $0x0,0xb0(%rsp)
  movq   %rax,%xmm2
  lea    D92(%rip),%rax
  mov    %rax,0x28(%rsp)
  mov    D19(%rip),%rax
  punpcklqdq %xmm2,%xmm0
  movups %xmm0,0x18(%rsp)
  mov    %rax,0x4(%rsp)
  cmp    $0x27ff,%rdi
  jbe    L27
  lea    D18(%rip),%rcx
  mov    $0x1,%ebp
  cmp    $0xfffff,%rdi
  ja     L38
L51:
  lea    0x30(%rsp),%r12
  movslq %ebp,%rbp
  mov    $0x80,%esi
  xor    %eax,%eax
  lea    D53(%rip),%rdx
  mov    %r12,%rdi
  call   <snprintf@plt>
  mov    0x10(%rsp,%rbp,8),%rcx
  movss  (%rsp,%rbp,4),%xmm1
  test   %rbx,%rbx
  js     L46
L65:
  pxor   %xmm0,%xmm0
  cvtsi2ss %rbx,%xmm0
L29:
  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    L1
  add    $0x140,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  ret
  nopl   0x0(%rax)
L38:
  cmp    $0x40000000,%rdi
  lea    D0(%rip),%rcx
  sbb    %ebp,%ebp
  add    $0x3,%ebp
  jmp    L51
  nopl   0x0(%rax,%rax,1)
L27:
  lea    0x30(%rsp),%r12
  lea    D76(%rip),%rcx
  xor    %eax,%eax
  mov    $0x80,%esi
  lea    D53(%rip),%rdx
  mov    %r12,%rdi
  call   <snprintf@plt>
  cmp    $0x2,%rbx
  lea    D100(%rip),%rcx
  lea    D2(%rip),%rax
  movss  D52(%rip),%xmm1
  cmovae %rax,%rcx
  test   %rbx,%rbx
  jns    L65
L46:
  mov    %rbx,%rax
  pxor   %xmm0,%xmm0
  and    $0x1,%ebx
  shr    %rax
  or     %rbx,%rax
  cvtsi2ss %rax,%xmm0
  addss  %xmm0,%xmm0
  jmp    L29
L1:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: extract_symbolic_data
arguments: data_label: D60
type: string
name: extract_symbolic_data
arguments: data_label: D42
type: string
name: extract_symbolic_data
arguments: data_label: D92
type: string
name: extract_symbolic_data
arguments: data_label: D19
type: byte[8]
name: extract_symbolic_data
arguments: data_label: D18
type: string
name: extract_symbolic_data
arguments: data_label: D53
type: string
name: extract_symbolic_data
arguments: data_label: D0
type: string
name: extract_symbolic_data
arguments: data_label: D76
type: string
name: extract_symbolic_data
arguments: data_label: D100
type: string
name: extract_symbolic_data
arguments: data_label: D2
type: string
name: extract_symbolic_data
arguments: data_label: D52
type: byte[4]

tool: D60: KB

tool: D42: MB

tool: D92: GB

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

tool: D18: %.1f

tool: D53: %s %%s

tool: D0: %.02f

tool: D76: %.0f

tool: D100: byte

tool: D2: bytes

tool: {"D52": [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);
}
```