user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<tile_to_linear_4x2>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %ecx,0x8(%rsp)
  mov    %ecx,%r13d
  imul   %edx,%r13d
  test   %ecx,%ecx
  je     L28
  mov    %rdi,%rbx
  mov    %rsi,%rbp
  mov    %edx,%r12d
  mov    %edx,%eax
  shl    $0x4,%eax
  mov    %eax,0xc(%rsp)
  movl   $0x0,0x4(%rsp)
  mov    $0x0,%r15d
  jmp    L84
L92:
  add    %r12d,%ecx
  add    $0x40,%edx
  cmp    %esi,%edx
  je     L38
L59:
  lea    0x10(%rcx),%eax
  cmp    %eax,%r13d
  jbe    L92
  mov    %edx,%eax
  movzbl 0x0(%rbp,%rax,1),%r10d
  lea    0x1(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r9d
  lea    0x2(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r8d
  lea    0x3(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%edi
  mov    %ecx,%eax
  mov    %r10b,(%rbx,%rax,1)
  lea    0x1(%rcx),%eax
  mov    %r9b,(%rbx,%rax,1)
  lea    0x2(%rcx),%eax
  mov    %r8b,(%rbx,%rax,1)
  lea    0x3(%rcx),%eax
  mov    %dil,(%rbx,%rax,1)
  lea    0x4(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r10d
  lea    0x5(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r9d
  lea    0x6(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r8d
  lea    0x7(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%edi
  lea    0x4(%rcx),%eax
  mov    %r10b,(%rbx,%rax,1)
  lea    0x5(%rcx),%eax
  mov    %r9b,(%rbx,%rax,1)
  lea    0x6(%rcx),%eax
  mov    %r8b,(%rbx,%rax,1)
  lea    0x7(%rcx),%eax
  mov    %dil,(%rbx,%rax,1)
  lea    0x8(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r10d
  lea    0x9(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r9d
  lea    0xa(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r8d
  lea    0xb(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%edi
  lea    0x8(%rcx),%eax
  mov    %r10b,(%rbx,%rax,1)
  lea    0x9(%rcx),%eax
  mov    %r9b,(%rbx,%rax,1)
  lea    0xa(%rcx),%eax
  mov    %r8b,(%rbx,%rax,1)
  lea    0xb(%rcx),%eax
  mov    %dil,(%rbx,%rax,1)
  lea    0xc(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r10d
  lea    0xd(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r9d
  lea    0xe(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%r8d
  lea    0xf(%rdx),%eax
  movzbl 0x0(%rbp,%rax,1),%edi
  lea    0xc(%rcx),%eax
  mov    %r10b,(%rbx,%rax,1)
  lea    0xd(%rcx),%eax
  mov    %r9b,(%rbx,%rax,1)
  lea    0xe(%rcx),%eax
  mov    %r8b,(%rbx,%rax,1)
  lea    0xf(%rcx),%eax
  mov    %dil,(%rbx,%rax,1)
  jmp    L92
L38:
  add    $0x10,%r14d
  cmp    %r14d,%r12d
  jbe    L9
L41:
  mov    %r15d,%ecx
  mov    %r14d,%edx
  mov    0x8(%rsp),%esi
  mov    %r12d,%edi
  call   <tile_4x2_read@plt>
  mov    0x4(%rsp),%esi
  lea    (%r14,%rsi,1),%ecx
  mov    %eax,%edx
  lea    0x400(%rax),%esi
  jmp    L59
L9:
  add    $0x10,%r15d
  mov    0xc(%rsp),%esi
  add    %esi,0x4(%rsp)
  cmp    %r15d,0x8(%rsp)
  jbe    L28
L84:
  mov    $0x0,%r14d
  test   %r12d,%r12d
  jne    L41
  jmp    L9
L28:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
void tile_to_linear_4x2(unsigned char *p_linear_addr, unsigned char *p_tiled_addr, unsigned int x_size, unsigned int y_size) {
  int trans_addr;
  unsigned int i, j, k, index;
  unsigned char data8[4];
  unsigned int max_index = x_size * y_size;
  for (i = 0; i < y_size; i = i + 16) {
    for (j = 0; j < x_size; j = j + 16) {
      trans_addr = tile_4x2_read(x_size, y_size, j, i);
      for (k = 0; k < 16; k++) {
        index = (i * x_size) + (x_size * k) + j;
        if (index + 16 >= max_index) {
          continue;
        }
        data8[0] = p_tiled_addr[trans_addr + 64 * k + 0];
        data8[1] = p_tiled_addr[trans_addr + 64 * k + 1];
        data8[2] = p_tiled_addr[trans_addr + 64 * k + 2];
        data8[3] = p_tiled_addr[trans_addr + 64 * k + 3];
        p_linear_addr[i * x_size + x_size * k + j] = data8[0];
        p_linear_addr[i * x_size + x_size * k + j + 1] = data8[1];
        p_linear_addr[i * x_size + x_size * k + j + 2] = data8[2];
        p_linear_addr[i * x_size + x_size * k + j + 3] = data8[3];
        data8[0] = p_tiled_addr[trans_addr + 64 * k + 4];
        data8[1] = p_tiled_addr[trans_addr + 64 * k + 5];
        data8[2] = p_tiled_addr[trans_addr + 64 * k + 6];
        data8[3] = p_tiled_addr[trans_addr + 64 * k + 7];
        p_linear_addr[i * x_size + x_size * k + j + 4] = data8[0];
        p_linear_addr[i * x_size + x_size * k + j + 5] = data8[1];
        p_linear_addr[i * x_size + x_size * k + j + 6] = data8[2];
        p_linear_addr[i * x_size + x_size * k + j + 7] = data8[3];
        data8[0] = p_tiled_addr[trans_addr + 64 * k + 8];
        data8[1] = p_tiled_addr[trans_addr + 64 * k + 9];
        data8[2] = p_tiled_addr[trans_addr + 64 * k + 10];
        data8[3] = p_tiled_addr[trans_addr + 64 * k + 11];
        p_linear_addr[i * x_size + x_size * k + j + 8] = data8[0];
        p_linear_addr[i * x_size + x_size * k + j + 9] = data8[1];
        p_linear_addr[i * x_size + x_size * k + j + 10] = data8[2];
        p_linear_addr[i * x_size + x_size * k + j + 11] = data8[3];
        data8[0] = p_tiled_addr[trans_addr + 64 * k + 12];
        data8[1] = p_tiled_addr[trans_addr + 64 * k + 13];
        data8[2] = p_tiled_addr[trans_addr + 64 * k + 14];
        data8[3] = p_tiled_addr[trans_addr + 64 * k + 15];
        p_linear_addr[i * x_size + x_size * k + j + 12] = data8[0];
        p_linear_addr[i * x_size + x_size * k + j + 13] = data8[1];
        p_linear_addr[i * x_size + x_size * k + j + 14] = data8[2];
        p_linear_addr[i * x_size + x_size * k + j + 15] = data8[3];
      }
    }
  }
}
```