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

```asm
<print_array_dual>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0xd8,%rsp
  mov    %rdi,0x20(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0xc8(%rsp)
  xor    %eax,%eax
  movslq %esi,%rax
  shr    $0x2,%rax
  mov    %eax,0x10(%rsp)
  test   %eax,%eax
  jle    L106
  movq   $0x0,0x28(%rsp)
  movl   $0x3,0x14(%rsp)
  lea    0x40(%rsp),%rax
  mov    %rax,0x18(%rsp)
  jmp    L38
L39:
  mov    0x20(%rsp),%rax
  mov    (%rax,%r15,4),%edi
  call   <ntoh32@plt>
  mov    %eax,%ebx
  mov    %eax,%r14d
  shr    $0x18,%r14d
  mov    %eax,%ebp
  sar    $0x10,%ebp
  mov    %bpl,0xf(%rsp)
  movzbl %bpl,%ebp
  mov    %eax,%r12d
  sar    $0x8,%r12d
  mov    %r12b,0xd(%rsp)
  movzbl %r12b,%r12d
  mov    %al,0xe(%rsp)
  movzbl %al,%r13d
  mov    %r14d,%r8d
  mov    %ebp,%ecx
  mov    %r12d,%edx
  mov    %r13d,%esi
  lea    D4(%rip),%rdi
  mov    $0x0,%eax
  call   <print@plt>
  sar    $0x18,%ebx
  cmp    $0x1f,%bl
  ja     L76
  mov    $0x2e,%r14d
L68:
  cmpb   $0x1f,0xf(%rsp)
  ja     L78
  mov    $0x2e,%ebp
L157:
  cmpb   $0x1f,0xd(%rsp)
  ja     L107
  mov    $0x2e,%r12d
L69:
  cmpb   $0x1f,0xe(%rsp)
  ja     L110
  mov    $0x2e,%r13d
L161:
  lea    0x3a(%rsp),%rbx
  mov    %r14d,%r9d
  mov    %ebp,%r8d
  mov    %r12d,%ecx
  mov    %r13d,%edx
  lea    D21(%rip),%rsi
  mov    %rbx,%rdi
  call   <sprintf@plt>
  mov    %rbx,%rsi
  mov    0x18(%rsp),%rdi
  call   <strcat@plt>
  add    $0x1,%r15
  cmp    %r15d,0x14(%rsp)
  jl     L34
L93:
  cmp    %r15d,0x10(%rsp)
  jg     L39
  mov    $0xff,%r8d
  mov    $0xff,%ecx
  mov    $0xff,%edx
  mov    $0xff,%esi
  lea    D4(%rip),%rdi
  mov    $0x0,%eax
  call   <print@plt>
  mov    $0xff,%edi
  call   <isascii@plt>
  test   %rax,%rax
  jne    L10
  mov    $0xff,%r13d
  mov    $0xff,%r12d
  mov    $0xff,%ebp
  movb   $0xff,0xe(%rsp)
  movb   $0xff,0xd(%rsp)
  movb   $0xff,0xf(%rsp)
  mov    $0x2e,%r14d
  jmp    L68
L76:
  mov    %r14d,%edi
  call   <isascii@plt>
  test   %rax,%rax
  mov    $0x2e,%eax
  cmove  %eax,%r14d
  jmp    L68
L10:
  mov    $0xff,%r13d
  mov    $0xff,%r12d
  mov    $0xff,%ebp
  movb   $0xff,0xe(%rsp)
  movb   $0xff,0xd(%rsp)
  mov    $0xff,%r14d
L78:
  mov    %ebp,%edi
  call   <isascii@plt>
  test   %rax,%rax
  mov    $0x2e,%eax
  cmove  %eax,%ebp
  jmp    L157
L107:
  mov    %r12d,%edi
  call   <isascii@plt>
  test   %rax,%rax
  mov    $0x2e,%eax
  cmove  %eax,%r12d
  jmp    L69
L110:
  mov    %r13d,%edi
  call   <isascii@plt>
  test   %rax,%rax
  mov    $0x2e,%eax
  cmove  %eax,%r13d
  jmp    L161
L34:
  mov    0x18(%rsp),%rsi
  lea    D2(%rip),%rdi
  mov    $0x0,%eax
  call   <print@plt>
  addl   $0x4,0x14(%rsp)
  addq   $0x4,0x28(%rsp)
  mov    0x28(%rsp),%rax
  cmp    %eax,0x10(%rsp)
  jle    L106
L38:
  movq   $0x0,0x40(%rsp)
  movq   $0x0,0x48(%rsp)
  movq   $0x0,0x50(%rsp)
  movq   $0x0,0x58(%rsp)
  movq   $0x0,0x60(%rsp)
  movq   $0x0,0x68(%rsp)
  movq   $0x0,0x70(%rsp)
  movq   $0x0,0x78(%rsp)
  movq   $0x0,0x80(%rsp)
  movq   $0x0,0x88(%rsp)
  movq   $0x0,0x90(%rsp)
  movq   $0x0,0x98(%rsp)
  movq   $0x0,0xa0(%rsp)
  movq   $0x0,0xa8(%rsp)
  movq   $0x0,0xb0(%rsp)
  movq   $0x0,0xb8(%rsp)
  mov    0x28(%rsp),%r15
  jmp    L93
L106:
  mov    0xc8(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L99
  add    $0xd8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L99:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: extract_symbolic_data
arguments: data_tag: D4
data_type: string
name: extract_symbolic_data
arguments: data_tag: D21
data_type: string
name: extract_symbolic_data
arguments: data_tag: D2
data_type: string

tool: D4: %02x %02x %02x %02x - 

tool: D21: %c%c%c%c 

tool: D2: %s


assistant: ```c
void print_array_dual(const unsigned char *array, int size) {
  int idx;
  int block;
  size /= sizeof(u_int32_t);
  for (block = 0; block < size; block += 4) {
    char ascii4[6];
    char ascii[128] = {
        0,
    };
    for (idx = block; idx < block + 4; idx++) {
      u_int32_t v;
      if (idx < size)
        v = ntoh32(((u_int32_t *)array)[idx]);
      else
        v = 0xffffffff;
      print("%02x %02x %02x %02x - ", ((unsigned char)(v)), ((unsigned char)(v >> 8)), ((unsigned char)(v >> 16)), ((unsigned char)(v >> 24)));
      sprintf(ascii4, "%c%c%c%c ", ((((unsigned char)(v)) >= 32 && isascii((unsigned char)(v))) ? ((unsigned char)(v)) : '.'), ((((unsigned char)(v >> 8)) >= 32 && isascii((unsigned char)(v >> 8))) ? ((unsigned char)(v >> 8)) : '.'), ((((unsigned char)(v >> 16)) >= 32 && isascii((unsigned char)(v >> 16))) ? ((unsigned char)(v >> 16)) : '.'), ((((unsigned char)(v >> 24)) >= 32 && isascii((unsigned char)(v >> 24))) ? ((unsigned char)(v >> 24)) : '.'));
      strcat(ascii, ascii4);
    }
    print("%s\n", ascii);
  }
}
```