user: Demonstrate the C code that generates the assembly output below:

```asm
<dump_mems>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    %rcx,-0x40(%rbp)
  mov    %r8,-0x48(%rbp)
  mov    %r9,-0x50(%rbp)
  cmpq   $0x0,-0x48(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  cmpq   $0x0,-0x40(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  cmpq   $0x0,-0x38(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  cmpq   $0x0,-0x28(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x48(%rbp),%rax
  add    $0x5,%rax
  shl    $0x2,%rax
  cmp    %rax,-0x30(%rbp)
  setae  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  mov    -0x50(%rbp),%rdx
  mov    -0x30(%rbp),%rsi
  mov    -0x28(%rbp),%rax
  mov    $0x10,%ecx
  mov    %rax,%rdi
  call   <hex@plt>
  addq   $0x10,-0x28(%rbp)
  subq   $0x10,-0x30(%rbp)
  mov    -0x28(%rbp),%rax
  movb   $0x3a,(%rax)
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  movb   $0x20,(%rax)
  addq   $0x2,-0x28(%rbp)
  subq   $0x2,-0x30(%rbp)
  mov    -0x48(%rbp),%rdi
  mov    -0x40(%rbp),%rcx
  mov    -0x38(%rbp),%rdx
  mov    -0x30(%rbp),%rsi
  mov    -0x28(%rbp),%rax
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <hexdump_mems@plt>
  mov    %eax,-0x14(%rbp)
  cmpl   $0x0,-0x14(%rbp)
  jns    L37
  mov    -0x14(%rbp),%eax
  jmp    L25
L37:
  mov    -0x48(%rbp),%rdx
  mov    -0x40(%rbp),%rax
  cmp    %rax,%rdx
  cmovbe %rdx,%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x10(%rbp),%rdx
  mov    %rdx,%rax
  add    %rax,%rax
  add    %rdx,%rax
  add    %rax,-0x28(%rbp)
  mov    -0x10(%rbp),%rdx
  mov    %rdx,%rax
  add    %rax,%rax
  add    %rdx,%rax
  sub    %rax,-0x30(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  jne    L4
  mov    D3(%rip),%rax
  mov    (%rax),%eax
  jmp    L25
L4:
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x20,(%rax)
  subq   $0x1,-0x30(%rbp)
  mov    -0x40(%rbp),%rax
  cmp    -0x48(%rbp),%rax
  jae    L24
  mov    -0x48(%rbp),%rax
  sub    -0x40(%rbp),%rax
  mov    %rax,%rdx
  mov    %rdx,%rax
  add    %rax,%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  cmp    -0x30(%rbp),%rax
  jbe    L20
  mov    D3(%rip),%rax
  mov    (%rax),%eax
  jmp    L25
L20:
  mov    -0x8(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    $0x20,%esi
  mov    %rax,%rdi
  call   <memset@plt>
  mov    -0x8(%rbp),%rax
  add    %rax,-0x28(%rbp)
  mov    -0x8(%rbp),%rax
  sub    %rax,-0x30(%rbp)
L24:
  mov    -0x48(%rbp),%rdi
  mov    -0x40(%rbp),%rcx
  mov    -0x38(%rbp),%rdx
  mov    -0x30(%rbp),%rsi
  mov    -0x28(%rbp),%rax
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <chardump_mems@plt>
L25:
  leave
  ret
```

assistant: ```c
int dump_mems(char *dest, size_t dsize, void const *data, size_t size, size_t amount, size_t offset) {
  size_t bump;
  int rc;
  assert(amount > 0);
  assert(size > 0);
  assert(data != NULL);
  assert(dest != NULL);
  assert(dsize >= sizeof(size_t) * 2 + 2 + (amount * 3) + 1 + amount + 1);
  hex(dest, dsize, offset, sizeof(size_t) * 2);
  dest += sizeof(size_t) * 2;
  dsize -= sizeof(size_t) * 2;
  dest[0] = ':';
  dest[1] = ' ';
  dest += 2;
  dsize -= 2;
  rc = hexdump_mems(dest, dsize, data, size, amount);
  if (rc < 0)
    return rc;
  bump = size < amount ? size : amount;
  dest += bump * 3;
  dsize -= bump * 3;
  if (dsize == 0)
    return ENOMEM;
  *dest++ = ' ';
  dsize--;
  if (size < amount) {
    size_t d = (amount - size) * 3;
    if (d > dsize)
      return ENOMEM;
    memset(dest, ' ', d);
    dest += d;
    dsize -= d;
  }
  return chardump_mems(dest, dsize, data, size, amount);
}
```