user: 请将以下的汇编代码转换成C语言代码:

```asm
<crack_datetime>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,%r14
  mov    %rsi,%r13
  mov    %rdx,%r12
  mov    %rcx,%rbp
  mov    %r8,%rbx
  mov    %r9,0x8(%rsp)
  mov    0x70(%rsp),%r15
  mov    %fs:0x28,%rax
  mov    %rax,0x28(%rsp)
  xor    %eax,%eax
  lea    0x20(%rsp),%rsi
  lea    0x18(%rsp),%rdi
  mov    0x78(%rsp),%rdx
  call   <get_datetime@plt>
  test   %r14,%r14
  je     L3
  mov    0x18(%rsp),%rcx
  mov    %rcx,%rdx
  shr    $0x2,%rdx
  movabs $0x28f5c28f5c28f5c3,%rsi
  mov    %rdx,%rax
  mul    %rsi
  mov    %rdx,%rax
  shr    $0x2,%rax
  and    $0xfffffffffffffffc,%rdx
  add    %rax,%rdx
  lea    (%rdx,%rdx,4),%rax
  shl    $0x2,%rax
  sub    %rax,%rcx
  cmp    $0x50,%ecx
  mov    $0x76c,%eax
  mov    $0x7d0,%edx
  cmovle %edx,%eax
  add    %ecx,%eax
  mov    %eax,(%r14)
L3:
  test   %r13,%r13
  je     L15
  mov    0x18(%rsp),%rdx
  shr    $0x2,%rdx
  movabs $0x28f5c28f5c28f5c3,%rsi
  mov    %rdx,%rax
  mul    %rsi
  mov    %rdx,%rcx
  shr    $0x2,%rcx
  shr    $0x4,%rdx
  mov    %rdx,%rax
  mul    %rsi
  mov    %rdx,%rax
  shr    $0x2,%rax
  and    $0xfffffffffffffffc,%rdx
  add    %rax,%rdx
  lea    (%rdx,%rdx,4),%rax
  shl    $0x2,%rax
  sub    %rax,%rcx
  mov    %rcx,0x0(%r13)
L15:
  test   %r12,%r12
  je     L33
  movabs $0x346dc5d63886594b,%rdx
  mov    %rdx,%rax
  mulq   0x18(%rsp)
  shr    $0xb,%rdx
  mov    %rdx,(%r12)
L33:
  test   %rbp,%rbp
  je     L60
  movabs $0x431bde82d7b634db,%rdx
  mov    %rdx,%rax
  mulq   0x20(%rsp)
  shr    $0x12,%rdx
  mov    %rdx,0x0(%rbp)
L60:
  test   %rbx,%rbx
  je     L14
  movabs $0x346dc5d63886594b,%rdx
  mov    %rdx,%rax
  mulq   0x20(%rsp)
  mov    %rdx,%rcx
  shr    $0xb,%rcx
  shr    $0xd,%rdx
  movabs $0x28f5c28f5c28f5c3,%rsi
  mov    %rdx,%rax
  mul    %rsi
  mov    %rdx,%rax
  shr    $0x2,%rax
  and    $0xfffffffffffffffc,%rdx
  add    %rax,%rdx
  lea    (%rdx,%rdx,4),%rax
  shl    $0x2,%rax
  sub    %rax,%rcx
  mov    %rcx,(%rbx)
L14:
  mov    0x8(%rsp),%rbx
  test   %rbx,%rbx
  je     L8
  mov    0x20(%rsp),%rdx
  shr    $0x2,%rdx
  movabs $0x28f5c28f5c28f5c3,%rsi
  mov    %rdx,%rax
  mul    %rsi
  mov    %rdx,%rcx
  shr    $0x2,%rcx
  shr    $0x4,%rdx
  mov    %rdx,%rax
  mul    %rsi
  mov    %rdx,%rax
  shr    $0x2,%rax
  and    $0xfffffffffffffffc,%rdx
  add    %rax,%rdx
  lea    (%rdx,%rdx,4),%rax
  shl    $0x2,%rax
  sub    %rax,%rcx
  mov    %rcx,(%rbx)
L8:
  test   %r15,%r15
  je     L53
  mov    0x20(%rsp),%rcx
  mov    %rcx,%rdx
  shr    $0x2,%rdx
  movabs $0x28f5c28f5c28f5c3,%rsi
  mov    %rdx,%rax
  mul    %rsi
  mov    %rdx,%rax
  shr    $0x2,%rax
  and    $0xfffffffffffffffc,%rdx
  add    %rax,%rdx
  lea    (%rdx,%rdx,4),%rax
  shl    $0x2,%rax
  sub    %rax,%rcx
  mov    %rcx,(%r15)
L53:
  mov    0x28(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L52
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L52:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
void crack_datetime(int *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *hundredths, unsigned long *age) {
  unsigned long date, time;
  get_datetime(&date, &time, age);
  if (year) {
    *year = date % 100;
    *year += *year > 80 ? 1900 : 2000;
  }
  if (month)
    *month = (date / 100) % 100;
  if (day)
    *day = date / 10000;
  if (hour)
    *hour = time / 1000000;
  if (minute)
    *minute = (time / 10000) % 100;
  if (second)
    *second = (time / 100) % 100;
  if (hundredths)
    *hundredths = time % 100;
}
```