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

```asm
<logging>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0xa0,%rsp
  mov    %rdi,-0x88(%rbp)
  mov    %rsi,-0x90(%rbp)
  mov    %rdx,-0x98(%rbp)
  mov    %ecx,-0x9c(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  cmpq   $0x0,-0x88(%rbp)
  je     L25
  movl   $0x0,-0x74(%rbp)
  cmpq   $0x0,-0x90(%rbp)
  je     L40
  mov    -0x90(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %eax,%esi
  mov    -0x88(%rbp),%rdx
  mov    -0x90(%rbp),%rax
  mov    %rdx,%rcx
  mov    %esi,%edx
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <fwrite@plt>
L40:
  mov    -0x88(%rbp),%rax
  mov    %rax,%rcx
  mov    $0x2,%edx
  mov    $0x1,%esi
  lea    D8(%rip),%rax
  mov    %rax,%rdi
  call   <fwrite@plt>
  jmp    L69
L59:
  mov    -0x74(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x98(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%edx
  lea    -0x70(%rbp),%rax
  lea    D21(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  lea    -0x70(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %eax,%esi
  mov    -0x88(%rbp),%rdx
  lea    -0x70(%rbp),%rax
  mov    %rdx,%rcx
  mov    %esi,%edx
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <fwrite@plt>
  addl   $0x1,-0x74(%rbp)
  mov    -0x74(%rbp),%eax
  and    $0xf,%eax
  test   %eax,%eax
  jne    L69
  mov    -0x74(%rbp),%eax
  cmp    -0x9c(%rbp),%eax
  jge    L69
  mov    -0x88(%rbp),%rax
  mov    %rax,%rcx
  mov    $0x1,%edx
  mov    $0x1,%esi
  lea    D29(%rip),%rax
  mov    %rax,%rdi
  call   <fwrite@plt>
  lea    -0x70(%rbp),%rax
  mov    $0x64,%edx
  mov    $0x20,%esi
  mov    %rax,%rdi
  call   <memset@plt>
  cmpq   $0x0,-0x90(%rbp)
  je     L69
  mov    -0x90(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  lea    0x2(%rax),%esi
  mov    -0x88(%rbp),%rdx
  lea    -0x70(%rbp),%rax
  mov    %rdx,%rcx
  mov    %esi,%edx
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <fwrite@plt>
L69:
  mov    -0x74(%rbp),%eax
  cmp    -0x9c(%rbp),%eax
  jl     L59
  mov    -0x88(%rbp),%rax
  mov    %rax,%rcx
  mov    $0x1,%edx
  mov    $0x1,%esi
  lea    D29(%rip),%rax
  mov    %rax,%rdi
  call   <fwrite@plt>
L25:
  nop
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L68
  call   <__stack_chk_fail@plt>
L68:
  leave
  ret
```

tool_calls: name: read_data
arguments: data_label: D8
type: string
name: read_data
arguments: data_label: D21
type: string
name: read_data
arguments: data_label: D29
type: string

tool: D8:   

tool: D21: %02x 

tool: D29: 


assistant: ```c
void logging(FILE *logfile, const char *prefix, const unsigned char *buffer, int len) {
  if (NULL != logfile) {
    int i = 0;
    if (NULL != prefix) {
      fwrite(prefix, 1, strlen(prefix), logfile);
    }
    fwrite("  ", 1, 2, logfile);
    while (i < len) {
      char buf[100];
      sprintf(buf, "%02x ", (unsigned char)buffer[i]);
      fwrite(buf, 1, strlen(buf), logfile);
      i++;
      if (0 == (i & 15) && (i < len)) {
        fwrite("\n", 1, 1, logfile);
        memset(buf, 0x20, sizeof(buf));
        if (NULL != prefix) {
          fwrite(buf, 1, strlen(prefix) + 2, logfile);
        }
      }
    }
    fwrite("\n", 1, 1, logfile);
  }
}
```