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

```asm
<ns_hexdump>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %esi,0x1c(%rsp)
  mov    %rdx,0x8(%rsp)
  mov    %ecx,%r13d
  mov    %fs:0x28,%rax
  mov    %rax,0x38(%rsp)
  xor    %eax,%eax
  movq   $0x0,0x20(%rsp)
  movq   $0x0,0x28(%rsp)
  movb   $0x0,0x30(%rsp)
  test   %esi,%esi
  jle    L96
  mov    %rdi,%r14
  mov    %esi,%r15d
  mov    $0x0,%r12d
  mov    $0x0,%ebx
  lea    0x20(%rsp),%rax
  mov    %rax,0x10(%rsp)
  jmp    L45
L94:
  mov    %r13d,%esi
  sub    %ebx,%esi
  movslq %ebx,%rdi
  add    0x8(%rsp),%rdi
  mov    0x18(%rsp),%ecx
  lea    D4(%rip),%rdx
  mov    $0x0,%eax
  call   <snprintf@plt>
  add    %eax,%ebx
L89:
  movzbl (%r14,%r12,1),%ecx
  mov    %r13d,%esi
  sub    %ebx,%esi
  movslq %ebx,%rdi
  add    0x8(%rsp),%rdi
  lea    D0(%rip),%rdx
  mov    $0x0,%eax
  call   <snprintf@plt>
  add    %eax,%ebx
  movzbl (%r14,%r12,1),%eax
  lea    -0x20(%rax),%edx
  cmp    $0x5f,%dl
  mov    $0x2e,%edx
  cmovae %edx,%eax
  movslq %ebp,%rdx
  mov    %al,0x20(%rsp,%rdx,1)
  add    $0x1,%ebp
  movslq %ebp,%rbp
  movb   $0x0,0x20(%rsp,%rbp,1)
  add    $0x1,%r12
  cmp    %r15,%r12
  je     L22
L45:
  mov    %r12d,0x18(%rsp)
  mov    %r12d,%eax
  sar    $0x1f,%eax
  shr    $0x1c,%eax
  lea    (%rax,%r12,1),%ebp
  and    $0xf,%ebp
  sub    %eax,%ebp
  test   $0xf,%r12b
  jne    L89
  test   %r12d,%r12d
  jle    L94
  mov    %r13d,%esi
  sub    %ebx,%esi
  movslq %ebx,%rdi
  add    0x8(%rsp),%rdi
  mov    0x10(%rsp),%rcx
  lea    D48(%rip),%rdx
  mov    $0x0,%eax
  call   <snprintf@plt>
  add    %eax,%ebx
  jmp    L94
L22:
  mov    0x1c(%rsp),%eax
  test   $0xf,%al
  je     L18
  mov    %eax,%ebp
  add    $0x1,%ebp
  lea    D30(%rip),%r14
  lea    D26(%rip),%r12
L33:
  mov    %r13d,%esi
  sub    %ebx,%esi
  movslq %ebx,%rdi
  add    0x8(%rsp),%rdi
  mov    %r14,%rcx
  mov    %r12,%rdx
  mov    $0x0,%eax
  call   <snprintf@plt>
  add    %eax,%ebx
  mov    %ebp,%eax
  and    $0xf,%eax
  add    $0x1,%ebp
  test   %eax,%eax
  jne    L33
L18:
  lea    0x20(%rsp),%rcx
  mov    %r13d,%esi
  sub    %ebx,%esi
  movslq %ebx,%rax
  mov    0x8(%rsp),%rdi
  add    %rax,%rdi
  lea    D5(%rip),%rdx
  mov    $0x0,%eax
  call   <snprintf@plt>
  add    %ebx,%eax
  mov    0x38(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L13
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L96:
  mov    $0x0,%ebx
  jmp    L18
L13:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: extract_symbolic_data
arguments: data_tag: D4
datatype: string
name: extract_symbolic_data
arguments: data_tag: D0
datatype: string
name: extract_symbolic_data
arguments: data_tag: D48
datatype: string
name: extract_symbolic_data
arguments: data_tag: D30
datatype: string
name: extract_symbolic_data
arguments: data_tag: D26
datatype: string
name: extract_symbolic_data
arguments: data_tag: D5
datatype: string

tool: D4: %04x 

tool: D0:  %02x

tool: D48:   %s


tool: D30:    

tool: D26: %s

tool: D5:   %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;
}
```