user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<milliseconds_to_long_string>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    $0x100,%edi
  call   <malloc@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  jne    L23
  mov    $0x0,%eax
  jmp    L126
L23:
  cmpq   $0x3e7,-0x38(%rbp)
  jg     L4
  mov    -0x18(%rbp),%rax
  lea    D38(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  mov    -0x18(%rbp),%rax
  jmp    L126
L4:
  cmpq   $0xea5f,-0x38(%rbp)
  jg     L77
  lea    D86(%rip),%rax
  mov    %rax,-0x20(%rbp)
  movq   $0x3e8,-0x28(%rbp)
  jmp    L146
L77:
  cmpq   $0x36ee7f,-0x38(%rbp)
  jg     L65
  lea    D41(%rip),%rax
  mov    %rax,-0x20(%rbp)
  movq   $0xea60,-0x28(%rbp)
  jmp    L146
L65:
  cmpq   $0x5265bff,-0x38(%rbp)
  jg     L56
  lea    D55(%rip),%rax
  mov    %rax,-0x20(%rbp)
  movq   $0x36ee80,-0x28(%rbp)
  jmp    L146
L56:
  cmpq   $0x240c83ff,-0x38(%rbp)
  jg     L63
  lea    D71(%rip),%rax
  mov    %rax,-0x20(%rbp)
  movq   $0x5265c00,-0x28(%rbp)
  jmp    L146
L63:
  movabs $0x7528acfff,%rax
  cmp    %rax,-0x38(%rbp)
  jg     L9
  lea    D44(%rip),%rax
  mov    %rax,-0x20(%rbp)
  movq   $0x240c8400,-0x28(%rbp)
  jmp    L146
L9:
  lea    D64(%rip),%rax
  mov    %rax,-0x20(%rbp)
  movabs $0x7528ad000,%rax
  mov    %rax,-0x28(%rbp)
L146:
  mov    -0x38(%rbp),%rax
  cqto
  idivq  -0x28(%rbp)
  mov    %rax,-0x10(%rbp)
  cmpq   $0x1,-0x10(%rbp)
  jne    L79
  lea    D29(%rip),%rax
  jmp    L54
L79:
  lea    D8(%rip),%rax
L54:
  mov    %rax,-0x8(%rbp)
  mov    -0x20(%rbp),%rsi
  mov    -0x10(%rbp),%rcx
  mov    -0x8(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  mov    %rsi,%r8
  mov    $0x100,%esi
  mov    %rax,%rdi
  call   <snprintf@plt>
  mov    -0x18(%rbp),%rax
L126:
  leave
  ret
```

tool_calls: name: read_data
arguments: data_tag: D38
type: string
name: read_data
arguments: data_tag: D86
type: string
name: read_data
arguments: data_tag: D41
type: string
name: read_data
arguments: data_tag: D55
type: string
name: read_data
arguments: data_tag: D71
type: string
name: read_data
arguments: data_tag: D44
type: string
name: read_data
arguments: data_tag: D64
type: string
name: read_data
arguments: data_tag: D29
type: string
name: read_data
arguments: data_tag: D8
type: string

tool: D38: less than one second

tool: D86: second

tool: D41: minute

tool: D55: hour

tool: D71: day

tool: D44: week

tool: D64: year

tool: D29: %lld %s

tool: D8: %lld %ss

assistant: ```c
char *milliseconds_to_long_string(long long ms) {
  long long div;
  char *name;
  char *str = malloc(256);
  if (!str)
    return NULL;
  if (ms < (long long)1000) {
    sprintf(str, "less than one second");
    return str;
  }
  if (ms < 60 * (long long)1000) {
    name = "second";
    div = (long long)1000;
  } else if (ms < 60 * 60 * (long long)1000) {
    name = "minute";
    div = 60 * (long long)1000;
  } else if (ms < 24 * 60 * 60 * (long long)1000) {
    name = "hour";
    div = 60 * 60 * (long long)1000;
  } else if (ms < 7 * 24 * 60 * 60 * (long long)1000) {
    name = "day";
    div = 24 * 60 * 60 * (long long)1000;
  } else if (ms < 52 * 7 * 24 * 60 * 60 * (long long)1000) {
    name = "week";
    div = 7 * 24 * 60 * 60 * (long long)1000;
  } else {
    name = "year";
    div = 52 * 7 * 24 * 60 * 60 * (long long)1000;
  }
  long long val = ms / div;
  char *fmt = 1 == val ? "%lld %s" : "%lld %ss";
  snprintf(str, 256, fmt, val, name);
  return str;
}
```