user: Please show me the C implementation that matches the assembly code listed below:

```asm
<cat_mem_ctl>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %esi,0x4(%rsp)
  mov    %ecx,0x8(%rsp)
  mov    %r9b,0xf(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  movq   $0x0,0x10(%rsp)
  imul   %edx,%edi
  test   %edi,%edi
  je     L13
  mov    %edx,%ebp
  mov    %r8d,%r15d
  mov    %edi,%r14d
  mov    $0x0,%ebx
L37:
  mov    %ebx,%eax
  mov    $0x0,%edx
  div    %ebp
  mov    %edx,%r13d
  mov    %eax,%r12d
  mov    %ebx,%ecx
  mov    0x4(%rsp),%edx
  mov    %ebp,%esi
  mov    0x8(%rsp),%edi
  call   <mem_sz2@plt>
  lea    0x10(%rsp),%rdi
  push   $0x0
  push   %rbx
  lea    -0x1(%rax),%r9d
  movsbl %r15b,%r8d
  mov    %r13d,%ecx
  mov    %r12d,%edx
  lea    D4(%rip),%rsi
  mov    $0x0,%eax
  call   <catf@plt>
  add    $0x10,%rsp
  test   %rax,%rax
  js     L60
  add    $0x1,%ebx
  cmp    %r14d,%ebx
  jne    L37
  mov    $0x0,%ebx
  lea    D1(%rip),%r12
L10:
  mov    %ebx,%eax
  mov    $0x0,%edx
  div    %ebp
  mov    %edx,%ecx
  lea    0x10(%rsp),%rdi
  mov    %ebx,%r9d
  movsbl 0xf(%rsp),%r8d
  mov    %eax,%edx
  mov    %r12,%rsi
  mov    $0x0,%eax
  call   <catf@plt>
  test   %rax,%rax
  js     L60
  add    $0x1,%ebx
  cmp    %r14d,%ebx
  jne    L10
L13:
  mov    0x10(%rsp),%rax
  jmp    L66
L60:
  mov    0x10(%rsp),%rdi
  call   <free@plt>
  mov    $0x0,%eax
L66:
  mov    0x18(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L67
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L67:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: unpack_data
arguments: data_label: D4
type_guessed: string
name: unpack_data
arguments: data_label: D1
type_guessed: string

tool: D4:         if(`enabled(%5$d)) begin
          en_%1$d_%2$d_%3$c <= 1;
          in_%1$d_%2$d_%3$c <= inputs_2[`in_from(%5$d)];
          addr_%1$d_%2$d_%3$c <= wraddr_%1$d_%2$d;
          wraddr_%1$d_%2$d <= wraddr_%1$d_%2$d == %4$d ? 0 : wraddr_%1$d_%2$d + 1;
        end
        else begin
          en_%1$d_%2$d_%3$c <= 0;
        end


tool: D1:         en_%1$d_%2$d_%3$c <= 1;
        addr_%1$d_%2$d_%3$c <= `raddr(%1$d);


assistant: ```c
char *cat_mem_ctl(unsigned inputs, unsigned period, unsigned n_mem, unsigned mem_sz, char write_class, char read_class) {
  char *s = NULL;
  unsigned i;
  for (i = 0; i < inputs * n_mem; ++i) {
    unsigned a = i / n_mem, b = i % n_mem;
    if (catf(&s,
             "        if(`enabled(%5$d)) begin\n"
             "          en_%1$d_%2$d_%3$c <= 1;\n"
             "          in_%1$d_%2$d_%3$c <= "
             "inputs_2[`in_from(%5$d)];\n"
             "          addr_%1$d_%2$d_%3$c <= wraddr_%1$d_%2$d;\n"
             "          wraddr_%1$d_%2$d <= wraddr_%1$d_%2$d "
             "== %4$d ? 0 : wraddr_%1$d_%2$d + 1;\n"
             "        end\n"
             "        else begin\n"
             "          en_%1$d_%2$d_%3$c <= 0;\n"
             "        end\n",
             a, b, write_class, mem_sz2(mem_sz, n_mem, period, i) - 1, i, 0) < 0)
      goto error;
  }
  for (i = 0; i < inputs * n_mem; ++i) {
    unsigned a = i / n_mem, b = i % n_mem;
    if (catf(&s,
             "        en_%1$d_%2$d_%3$c <= 1;\n"
             "        addr_%1$d_%2$d_%3$c <= `raddr(%1$d);\n",
             a, b, read_class, i) < 0)
      goto error;
  }
  return s;
error:
  free(s);
  return NULL;
}
```