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

```asm
<ns_hexdump>:
  endbr64
  push   %r15
  pxor   %xmm0,%xmm0
  push   %r14
  push   %r13
  push   %r12
  mov    %ecx,%r12d
  push   %rbp
  mov    %rdx,%rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %esi,0x1c(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x38(%rsp)
  xor    %eax,%eax
  movb   $0x0,0x30(%rsp)
  movaps %xmm0,0x20(%rsp)
  test   %esi,%esi
  jle    L8
  mov    %esi,%eax
  xor    %r8d,%r8d
  mov    %rdi,%r13
  xor    %r14d,%r14d
  mov    %rax,0x8(%rsp)
  lea    0x20(%rsp),%rax
  mov    %r8d,%ebx
  mov    %rax,0x10(%rsp)
  jmp    L23
  nopl   0x0(%rax)
L21:
  movslq 0x4(%rsp),%rdx
  mov    %al,0x20(%rsp,%rdx,1)
  lea    0x1(%rdx),%r15d
L76:
  movslq %r15d,%r15
  add    $0x1,%r14
  movb   $0x0,0x20(%rsp,%r15,1)
  cmp    %r14,0x8(%rsp)
  je     L32
L23:
  mov    %r14d,%eax
  mov    %r14d,%r9d
  mov    %ebx,%r15d
  and    $0xf,%eax
  mov    %eax,0x4(%rsp)
  jne    L99
  test   %r14,%r14
  je     L83
  movslq %ebx,%rdi
  mov    0x10(%rsp),%rcx
  mov    %r12d,%esi
  xor    %eax,%eax
  sub    %ebx,%esi
  add    %rbp,%rdi
  mov    %r14d,0x18(%rsp)
  lea    D10(%rip),%rdx
  call   <snprintf@plt>
  mov    0x18(%rsp),%r9d
  lea    (%rbx,%rax,1),%r15d
  mov    %r15d,%ebx
L83:
  movslq %ebx,%rdi
  mov    %r12d,%esi
  mov    %r9d,%ecx
  xor    %eax,%eax
  sub    %ebx,%esi
  add    %rbp,%rdi
  lea    D3(%rip),%rdx
  call   <snprintf@plt>
  add    %eax,%r15d
  mov    %r15d,%ebx
L99:
  movslq %ebx,%rdi
  movzbl 0x0(%r13,%r14,1),%ecx
  mov    %r12d,%esi
  xor    %eax,%eax
  sub    %ebx,%esi
  lea    D53(%rip),%rdx
  add    %rbp,%rdi
  call   <snprintf@plt>
  lea    (%r15,%rax,1),%r8d
  movzbl 0x0(%r13,%r14,1),%eax
  mov    %r8d,%ebx
  lea    -0x20(%rax),%edx
  cmp    $0x5e,%dl
  jbe    L21
  movslq 0x4(%rsp),%rax
  movb   $0x2e,0x20(%rsp,%rax,1)
  lea    0x1(%rax),%r15d
  jmp    L76
L32:
  mov    %r8d,%r15d
  testb  $0xf,0x1c(%rsp)
  je     L5
  mov    0x1c(%rsp),%r14d
  lea    D13(%rip),%r13
  lea    D28(%rip),%rbx
  add    $0x1,%r14d
  nopl   0x0(%rax)
L31:
  movslq %r15d,%rdi
  mov    %r12d,%esi
  mov    %r13,%rcx
  mov    %rbx,%rdx
  sub    %r15d,%esi
  add    %rbp,%rdi
  xor    %eax,%eax
  call   <snprintf@plt>
  add    %eax,%r15d
  mov    %r14d,%eax
  add    $0x1,%r14d
  and    $0xf,%eax
  test   %eax,%eax
  jne    L31
L5:
  movslq %r15d,%rax
  sub    %r15d,%r12d
  add    %rax,%rbp
L59:
  mov    0x10(%rsp),%rcx
  mov    %r12d,%esi
  mov    %rbp,%rdi
  xor    %eax,%eax
  lea    D40(%rip),%rdx
  call   <snprintf@plt>
  add    %r15d,%eax
  mov    0x38(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L104
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  cs nopw 0x0(%rax,%rax,1)
L8:
  lea    0x20(%rsp),%rax
  xor    %r15d,%r15d
  mov    %rax,0x10(%rsp)
  jmp    L59
L104:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: parse_data
arguments: label: D10
type: string
name: parse_data
arguments: label: D3
type: string
name: parse_data
arguments: label: D53
type: string
name: parse_data
arguments: label: D13
type: string
name: parse_data
arguments: label: D28
type: string
name: parse_data
arguments: label: D40
type: string

tool: D10:   %s


tool: D3: %04x 

tool: D53:  %02x

tool: D13:    

tool: D28: %s

tool: D40:   %s



assistant: ```c
int ns_hexdump(const void *buf, int len, char *dst, int dst_len) {
  const unsigned char *p = (const unsigned char *)buf;
  char ascii[17] = "";
  int i, idx, n = 0;
  for (i = 0; i < len; i++) {
    idx = i % 16;
    if (idx == 0) {
      if (i > 0)
        n += snprintf(dst + n, dst_len - n, "  %s\n", ascii);
      n += snprintf(dst + n, dst_len - n, "%04x ", i);
    }
    n += snprintf(dst + n, dst_len - n, " %02x", p[i]);
    ascii[idx] = p[i] < 0x20 || p[i] > 0x7e ? '.' : p[i];
    ascii[idx + 1] = '\0';
  }
  while (i++ % 16)
    n += snprintf(dst + n, dst_len - n, "%s", "   ");
  n += snprintf(dst + n, dst_len - n, "  %s\n\n", ascii);
  return n;
}
```