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

```asm
<psf_hexdump>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %esi,-0x3c(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  cmpq   $0x0,-0x28(%rbp)
  je     L76
  cmpl   $0x0,-0x3c(%rbp)
  jle    L19
  lea    D11(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  movl   $0x0,-0x30(%rbp)
  jmp    L150
L151:
  lea    -0x20(%rbp),%rax
  mov    $0x11,%edx
  mov    $0x20,%esi
  mov    %rax,%rdi
  call   <memset@plt>
  mov    -0x30(%rbp),%eax
  mov    %eax,%esi
  lea    D21(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  movl   $0x0,-0x2c(%rbp)
  jmp    L162
L60:
  mov    -0x30(%rbp),%edx
  mov    -0x2c(%rbp),%eax
  add    %edx,%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  movzbl %al,%edx
  cmpl   $0x8,-0x2c(%rbp)
  jne    L168
  lea    D47(%rip),%rax
  jmp    L22
L168:
  lea    D7(%rip),%rax
L22:
  mov    %edx,%esi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  mov    -0x30(%rbp),%edx
  mov    -0x2c(%rbp),%eax
  add    %edx,%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <psf_isprint@plt>
  test   %rax,%rax
  je     L142
  mov    -0x30(%rbp),%edx
  mov    -0x2c(%rbp),%eax
  add    %edx,%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  jmp    L85
L142:
  mov    $0x2e,%eax
L85:
  mov    -0x2c(%rbp),%edx
  movslq %edx,%rdx
  mov    %al,-0x20(%rbp,%rdx,1)
  addl   $0x1,-0x2c(%rbp)
L162:
  cmpl   $0xf,-0x2c(%rbp)
  jg     L110
  mov    -0x30(%rbp),%edx
  mov    -0x2c(%rbp),%eax
  add    %edx,%eax
  cmp    %eax,-0x3c(%rbp)
  jg     L60
L110:
  cmpl   $0x8,-0x2c(%rbp)
  jg     L141
  mov    $0x20,%edi
  call   <putchar@plt>
  jmp    L141
L109:
  lea    D31(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  addl   $0x1,-0x2c(%rbp)
L141:
  cmpl   $0xf,-0x2c(%rbp)
  jle    L109
  movb   $0x0,-0x10(%rbp)
  lea    -0x20(%rbp),%rax
  mov    %rax,%rsi
  lea    D22(%rip),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  addl   $0x10,-0x30(%rbp)
L150:
  mov    -0x30(%rbp),%eax
  cmp    -0x3c(%rbp),%eax
  jl     L151
  lea    D11(%rip),%rax
  mov    %rax,%rdi
  call   <puts@plt>
  jmp    L130
L76:
  nop
  jmp    L130
L19:
  nop
L130:
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L17
  call   <__stack_chk_fail@plt>
L17:
  leave
  ret
```

tool_calls: name: extract_symbolic_data
arguments: data_label: D11
type_infered: string
name: extract_symbolic_data
arguments: data_label: D21
type_infered: string
name: extract_symbolic_data
arguments: data_label: D47
type_infered: string
name: extract_symbolic_data
arguments: data_label: D7
type_infered: string
name: extract_symbolic_data
arguments: data_label: D31
type_infered: string
name: extract_symbolic_data
arguments: data_label: D22
type_infered: string

tool: 

tool: D21: %08X: 

tool: D47:  %02X 

tool: D7: %02X 

tool: D31:    

tool: D22:  %s


assistant: ```c
void psf_hexdump(const void *ptr, int len) {
  const char *data;
  char ascii[17];
  int k, m;
  if ((data = ptr) == NULL)
    return;
  if (len <= 0)
    return;
  puts("");
  for (k = 0; k < len; k += 16) {
    memset(ascii, ' ', sizeof(ascii));
    printf("%08X: ", k);
    for (m = 0; m < 16 && k + m < len; m++) {
      printf(m == 8 ? " %02X " : "%02X ", data[k + m] & 0xFF);
      ascii[m] = psf_isprint(data[k + m]) ? data[k + m] : '.';
    };
    if (m <= 8)
      printf(" ");
    for (; m < 16; m++)
      printf("   ");
    ascii[16] = 0;
    printf(" %s\n", ascii);
  };
  puts("");
}
```