user: Converte this assembly snippet into its equivalent C code:

```asm
<dump_memory>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,%rbx
  mov    %esi,%r15d
  lea    D82(%rip),%rax
  push   %rax
  lea    D77(%rip),%rax
  push   %rax
  lea    D21(%rip),%r9
  lea    D120(%rip),%r8
  lea    D37(%rip),%rcx
  lea    D112(%rip),%rdx
  lea    D38(%rip),%rsi
  lea    D16(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  add    $0x10,%rsp
  test   %r15d,%r15d
  jle    L47
  mov    $0x0,%ebp
  jmp    L69
L4:
  mov    %r12d,%edx
  mov    %rbx,%rsi
  lea    D111(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
L108:
  mov    %ebp,%edi
  call   <hasShort@plt>
  test   %rax,%rax
  jne    L31
L83:
  mov    %ebp,%edi
  call   <hasIntAndFloat@plt>
  test   %rax,%rax
  jne    L17
L106:
  mov    %ebp,%edi
  call   <hasDouble@plt>
  test   %rax,%rax
  jne    L103
L84:
  mov    $0xa,%edi
  call   <putchar@plt>
  add    $0x1,%ebp
  add    $0x1,%rbx
  cmp    %ebp,%r15d
  je     L47
L69:
  movzwl (%rbx),%r13d
  mov    (%rbx),%r14d
  movsd  (%rbx),%xmm1
  movsd  %xmm1,0x8(%rsp)
  movzbl (%rbx),%r12d
  mov    %r12d,%edi
  call   <isCharVisible@plt>
  test   %rax,%rax
  je     L4
  mov    %r12d,%ecx
  mov    %r12d,%edx
  mov    %rbx,%rsi
  lea    D19(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L108
L31:
  movzwl %r13w,%esi
  lea    D62(%rip),%rdi
  mov    $0x0,%eax
  call   <printf@plt>
  jmp    L83
L17:
  movd   %r14d,%xmm2
  pxor   %xmm0,%xmm0
  cvtss2sd %xmm2,%xmm0
  mov    %r14d,%esi
  lea    D113(%rip),%rdi
  mov    $0x1,%eax
  call   <printf@plt>
  jmp    L106
L103:
  movsd  0x8(%rsp),%xmm0
  lea    D57(%rip),%rdi
  mov    $0x1,%eax
  call   <printf@plt>
  jmp    L84
L47:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

tool_calls: name: read_data
arguments: data_label: D82
type: string
name: read_data
arguments: data_label: D77
type: string
name: read_data
arguments: data_label: D21
type: string
name: read_data
arguments: data_label: D120
type: string
name: read_data
arguments: data_label: D37
type: string
name: read_data
arguments: data_label: D112
type: string
name: read_data
arguments: data_label: D38
type: string
name: read_data
arguments: data_label: D16
type: string
name: read_data
arguments: data_label: D111
type: string
name: read_data
arguments: data_label: D19
type: string
name: read_data
arguments: data_label: D62
type: string
name: read_data
arguments: data_label: D113
type: string
name: read_data
arguments: data_label: D57
type: string

tool: D82: doubleFloat

tool: D77: float

tool: D21: integer

tool: D120: short

tool: D37: hexCh

tool: D112: char

tool: D38: address

tool: D16: %s		%s	%s	%s	%s		%s		%s


tool: D111: %8p:	?	0x%02x	

tool: D19: %8p:	%c	0x%02x	

tool: D62: %+5hu	

tool: D113: %+10d	%+e	

tool: D57: %+e

assistant: ```c
void dump_memory(void *p, int len) {
  void *memAddress;
  unsigned char mChar;
  unsigned short mShort;
  unsigned int mInt;
  float mFloat;
  double mDouble;
  int i;
  printf("%s\t\t%s\t%s\t%s\t%s\t\t%s\t\t%s\n", "address", "char", "hexCh", "short", "integer", "float", "doubleFloat");
  for (i = 0; i < len; i++) {
    memAddress = p + i;
    mChar = *(unsigned char *)(p + i);
    mShort = *(unsigned short *)(p + i);
    mInt = *(unsigned int *)(p + i);
    mFloat = *(float *)(p + i);
    mDouble = *(double *)(p + i);
    if (isCharVisible(mChar))
      printf("%8p:\t%c\t0x%02x\t", memAddress, mChar, mChar);
    else
      printf("%8p:\t?\t0x%02x\t", memAddress, mChar);
    if (hasShort(i))
      printf("%+5hu\t", mShort);
    if (hasIntAndFloat(i))
      printf("%+10d\t%+e\t", mInt, mFloat);
    if (hasDouble(i))
      printf("%+e", mDouble);
    printf("\n");
  }
}
```