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

```asm
<factorial>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  lea    -0x7a1000(%rsp),%r11
L82:
  sub    $0x1000,%rsp
  orq    $0x0,(%rsp)
  cmp    %r11,%rsp
  jne    L82
  sub    $0x240,%rsp
  mov    %rdi,-0x7a1238(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  cmpq   $0x0,-0x7a1238(%rbp)
  jne    L5
  lea    D12(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  jmp    L133
L5:
  movq   $0x0,-0x7a1228(%rbp)
  mov    -0x7a1238(%rbp),%rax
  mov    %rax,-0x7a1220(%rbp)
  movq   $0x0,-0x7a1218(%rbp)
  movq   $0x0,-0x7a1210(%rbp)
  jmp    L0
L44:
  mov    -0x7a1228(%rbp),%rcx
  lea    0x1(%rcx),%rax
  mov    %rax,-0x7a1228(%rbp)
  mov    -0x7a1220(%rbp),%rsi
  movabs $0xcccccccccccccccd,%rdx
  mov    %rsi,%rax
  mul    %rdx
  shr    $0x3,%rdx
  mov    %rdx,%rax
  shl    $0x2,%rax
  add    %rdx,%rax
  add    %rax,%rax
  sub    %rax,%rsi
  mov    %rsi,%rdx
  mov    %rdx,-0x7a1200(%rbp,%rcx,8)
  mov    -0x7a1220(%rbp),%rax
  movabs $0xcccccccccccccccd,%rdx
  mul    %rdx
  mov    %rdx,%rax
  shr    $0x3,%rax
  mov    %rax,-0x7a1220(%rbp)
  addq   $0x1,-0x7a1218(%rbp)
L0:
  cmpq   $0x0,-0x7a1220(%rbp)
  jne    L44
  mov    -0x7a1238(%rbp),%rax
  mov    %rax,-0x7a1208(%rbp)
  jmp    L131
L76:
  movq   $0x0,-0x7a1228(%rbp)
  jmp    L12
L6:
  mov    -0x7a1228(%rbp),%rax
  mov    -0x7a1200(%rbp,%rax,8),%rax
  mov    -0x7a1208(%rbp),%rdx
  sub    $0x1,%rdx
  imul   %rax,%rdx
  mov    -0x7a1210(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x7a1220(%rbp)
  mov    -0x7a1220(%rbp),%rcx
  movabs $0xcccccccccccccccd,%rdx
  mov    %rcx,%rax
  mul    %rdx
  shr    $0x3,%rdx
  mov    %rdx,%rax
  shl    $0x2,%rax
  add    %rdx,%rax
  add    %rax,%rax
  sub    %rax,%rcx
  mov    %rcx,%rdx
  mov    -0x7a1228(%rbp),%rax
  mov    %rdx,-0x7a1200(%rbp,%rax,8)
  mov    -0x7a1220(%rbp),%rax
  movabs $0xcccccccccccccccd,%rdx
  mul    %rdx
  mov    %rdx,%rax
  shr    $0x3,%rax
  mov    %rax,-0x7a1210(%rbp)
  addq   $0x1,-0x7a1228(%rbp)
L12:
  mov    -0x7a1228(%rbp),%rax
  cmp    -0x7a1218(%rbp),%rax
  jb     L6
  jmp    L50
L110:
  mov    -0x7a1228(%rbp),%rcx
  lea    0x1(%rcx),%rax
  mov    %rax,-0x7a1228(%rbp)
  mov    -0x7a1210(%rbp),%rsi
  movabs $0xcccccccccccccccd,%rdx
  mov    %rsi,%rax
  mul    %rdx
  shr    $0x3,%rdx
  mov    %rdx,%rax
  shl    $0x2,%rax
  add    %rdx,%rax
  add    %rax,%rax
  sub    %rax,%rsi
  mov    %rsi,%rdx
  mov    %rdx,-0x7a1200(%rbp,%rcx,8)
  mov    -0x7a1210(%rbp),%rax
  movabs $0xcccccccccccccccd,%rdx
  mul    %rdx
  mov    %rdx,%rax
  shr    $0x3,%rax
  mov    %rax,-0x7a1210(%rbp)
  addq   $0x1,-0x7a1218(%rbp)
L50:
  cmpq   $0x0,-0x7a1210(%rbp)
  jne    L110
  subq   $0x1,-0x7a1208(%rbp)
L131:
  cmpq   $0x1,-0x7a1208(%rbp)
  ja     L76
  mov    -0x7a1238(%rbp),%rax
  mov    %rax,%rsi
  lea    D16(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x7a1218(%rbp),%rax
  mov    %rax,-0x7a1228(%rbp)
  jmp    L31
L124:
  mov    -0x7a1228(%rbp),%rax
  sub    $0x1,%rax
  mov    -0x7a1200(%rbp,%rax,8),%rax
  mov    %rax,%rsi
  lea    D34(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  subq   $0x1,-0x7a1228(%rbp)
L31:
  cmpq   $0x0,-0x7a1228(%rbp)
  jne    L124
  lea    D37(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
L133:
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L127
  call   <__stack_chk_fail@plt>
L127:
  leave
  ret
```

tool_calls: name: parse_data
arguments: tag: D12
data_type: string
name: parse_data
arguments: tag: D16
data_type: string
name: parse_data
arguments: tag: D34
data_type: string
name: parse_data
arguments: tag: D37
data_type: string

tool: D12: 
	0! = 1


tool: D16: 
	%lu! = 

tool: D34: %lu

tool: D37: 


assistant: ```c
void factorial(unsigned long n) {
  if (n == 0) {
    printf("\n\t0! = 1\n\n");
    return;
  }
  unsigned long a[(999999L)];
  unsigned long index = 0;
  unsigned long tmp = n;
  unsigned long digits = 0;
  unsigned long carry = 0;
  while (tmp > 0) {
    a[index++] = tmp % 10;
    tmp /= 10;
    digits++;
  }
  unsigned long m;
  for (m = n; m > 1; --m) {
    for (index = 0; index < digits; ++index) {
      tmp = a[index] * (m - 1) + carry;
      a[index] = tmp % 10;
      carry = tmp / 10;
    }
    while (carry > 0) {
      a[index++] = carry % 10;
      carry /= 10;
      digits++;
    }
  }
  printf("\n\t%lu! = ", n);
  for (index = digits; index > 0; --index)
    printf("%lu", a[index - 1]);
  printf("\n\n");
}
```