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

```asm
<print_duration>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x20,%rsp
  mov    %rdi,-0x18(%rbp)
  cmpq   $0xf4240,-0x18(%rbp)
  jbe    L64
  mov    -0x18(%rbp),%rcx
  movabs $0x346dc5d63886594b,%rdx
  mov    %rcx,%rax
  mul    %rdx
  mov    %rdx,%rax
  shr    $0xb,%rax
  imul   $0x2710,%rax,%rdx
  mov    %rcx,%rax
  sub    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  cmpq   $0x1387,-0x8(%rbp)
  jbe    L55
  addq   $0x2710,-0x18(%rbp)
L55:
  mov    -0x18(%rbp),%rcx
  movabs $0x431bde82d7b634db,%rdx
  mov    %rcx,%rax
  mul    %rdx
  mov    %rdx,%rax
  shr    $0x12,%rax
  imul   $0xf4240,%rax,%rdx
  mov    %rcx,%rax
  sub    %rdx,%rax
  mov    %eax,%edx
  mov    $0xd1b71759,%eax
  imul   %rdx,%rax
  shr    $0x20,%rax
  shr    $0xd,%eax
  mov    -0x18(%rbp),%rdx
  mov    %edx,%edx
  imul   $0x431bde83,%rdx,%rdx
  shr    $0x20,%rdx
  shr    $0x12,%edx
  mov    %edx,%ecx
  mov    %eax,%edx
  mov    %rcx,%rsi
  lea    D21(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L70
L64:
  cmpq   $0x186a0,-0x18(%rbp)
  jbe    L51
  mov    -0x18(%rbp),%rcx
  mov    %rcx,%rax
  shr    $0x3,%rax
  movabs $0x20c49ba5e353f7cf,%rdx
  mul    %rdx
  mov    %rdx,%rax
  shr    $0x4,%rax
  imul   $0x3e8,%rax,%rdx
  mov    %rcx,%rax
  sub    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  cmpq   $0x1f3,-0x8(%rbp)
  jbe    L81
  addq   $0x3e8,-0x18(%rbp)
L81:
  mov    -0x18(%rbp),%rax
  mov    %eax,%eax
  imul   $0x10624dd3,%rax,%rax
  shr    $0x20,%rax
  shr    $0x6,%eax
  mov    %eax,%eax
  mov    %rax,%rsi
  lea    D39(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L70
L51:
  cmpq   $0x3e8,-0x18(%rbp)
  jbe    L86
  mov    -0x18(%rbp),%rcx
  mov    %rcx,%rax
  shr    $0x2,%rax
  movabs $0x28f5c28f5c28f5c3,%rdx
  mul    %rdx
  shr    $0x2,%rdx
  mov    %rdx,%rax
  shl    $0x2,%rax
  add    %rdx,%rax
  lea    0x0(,%rax,4),%rdx
  add    %rdx,%rax
  shl    $0x2,%rax
  sub    %rax,%rcx
  mov    %rcx,%rdx
  mov    %rdx,-0x8(%rbp)
  cmpq   $0x31,-0x8(%rbp)
  jbe    L18
  addq   $0x64,-0x18(%rbp)
L18:
  mov    -0x18(%rbp),%rcx
  mov    %rcx,%rax
  shr    $0x3,%rax
  movabs $0x20c49ba5e353f7cf,%rdx
  mul    %rdx
  mov    %rdx,%rax
  shr    $0x4,%rax
  imul   $0x3e8,%rax,%rdx
  mov    %rcx,%rax
  sub    %rdx,%rax
  mov    %eax,%eax
  imul   $0x51eb851f,%rax,%rax
  shr    $0x20,%rax
  shr    $0x5,%eax
  mov    -0x18(%rbp),%rdx
  mov    %edx,%edx
  imul   $0x10624dd3,%rdx,%rdx
  shr    $0x20,%rdx
  shr    $0x6,%edx
  mov    %edx,%ecx
  mov    %eax,%edx
  mov    %rcx,%rsi
  lea    D4(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L70
L86:
  mov    -0x18(%rbp),%rax
  mov    %rax,%rsi
  lea    D10(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  nop
L70:
  leave
  ret
```

tool_calls: name: unpack_data
arguments: tag: D21
type: string
name: unpack_data
arguments: tag: D39
type: string
name: unpack_data
arguments: tag: D4
type: string
name: unpack_data
arguments: tag: D10
type: string

tool: D21: %u.%02u ms

tool: D39: %u us

tool: D4: %u.%01u us

tool: D10: %lu ns

assistant: ```c
void print_duration(unsigned long duration) {
  unsigned long tmp;
  if (duration > 1000000) {
    tmp = duration % 10000;
    if (tmp >= 5000)
      duration += 10000;
    printf("%u.%02u ms", ((unsigned int)duration / 1000000), ((unsigned int)(duration % 1000000) / 10000));
  } else if (duration > 100000) {
    tmp = duration % 1000;
    if (tmp >= 500)
      duration += 1000;
    printf("%u us", ((unsigned int)duration / 1000));
  } else if (duration > 1000) {
    tmp = duration % 100;
    if (tmp >= 50)
      duration += 100;
    printf("%u.%01u us", ((unsigned int)duration / 1000), ((unsigned int)(duration % 1000) / 100));
  } else
    printf("%lu ns", duration);
  return;
}
```