user: Translate the below assembly code into C programming language:

```asm
<patch_hdr>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %rdi,%rbx
  mov    %rsi,%rbp
  mov    %rdx,%r14
  mov    %rcx,%r13
  mov    %r8,%r12
  mov    %r9,%r15
  mov    %fs:0x28,%rax
  mov    %rax,0x38(%rsp)
  xor    %eax,%eax
  lea    0x8(%rsp),%rcx
  mov    %rsp,%rdx
  sub    $0x8,%rsp
  lea    0x38(%rsp),%rax
  push   %rax
  lea    0x38(%rsp),%rax
  push   %rax
  lea    0x38(%rsp),%rax
  push   %rax
  lea    0x38(%rsp),%r9
  lea    0x30(%rsp),%r8
  call   <parse_hdr@plt>
  mov    %rax,%rdx
  add    $0x20,%rsp
  mov    $0x0,%eax
  cmp    %rbp,%rdx
  jne    L32
  mov    0x8(%rsp),%rdx
  lea    0x1c(%rdx),%rcx
  cmp    %rbp,%rcx
  jne    L32
  cmp    $0x10,%rdx
  ja     L74
L29:
  mov    0x28(%rsp),%rcx
  mov    0x18(%rsp),%rsi
  test   %r12,%r12
  jne    L5
  mov    0x20(%rsp),%rax
  imul   %rax,%r14
  shr    $0x2,%rax
  movabs $0x28f5c28f5c28f5c3,%rdx
  mul    %rdx
  shr    $0x2,%rdx
  mov    %rdx,%r12
  movabs $0xcccccccccccccccd,%rdx
  mov    %r13,%rax
  mul    %rdx
  shr    $0x3,%rdx
  imul   %rdx,%r12
  shr    $0x3,%r12
  movabs $0x20c49ba5e353f7cf,%rdx
  mov    %r12,%rax
  mul    %rdx
  shr    $0x4,%rdx
  add    %r14,%rdx
  mov    %rdx,%r12
  jne    L5
  mov    $0xffffffff,%eax
  mov    %rax,(%rsp)
  lea    -0x24(%rax),%rax
  mov    %rax,0x30(%rsp)
  jmp    L46
L74:
  lea    0x14(%rbx,%rdx,1),%rsi
  lea    0x24(%rbx),%rdi
  mov    $0x8,%edx
  call   <memmove@plt>
  movb   $0x10,0x10(%rbx)
  movb   $0x0,0x11(%rbx)
  movb   $0x0,0x12(%rbx)
  movb   $0x0,0x13(%rbx)
  movq   $0x10,0x8(%rsp)
  mov    $0x2c,%ebp
  jmp    L29
L5:
  add    $0x7,%rcx
  shr    $0x3,%rcx
  imul   %rsi,%rcx
  imul   %r12,%rcx
  mov    %rcx,0x30(%rsp)
  add    $0x24,%rcx
  mov    %rcx,(%rsp)
L46:
  test   %r15,%r15
  je     L23
  mov    0x30(%rsp),%rax
  mov    %rax,(%r15)
L23:
  mov    (%rsp),%rax
  mov    %al,0x4(%rbx)
  movzbl %ah,%ecx
  mov    %cl,0x5(%rbx)
  mov    %rax,%rdx
  shr    $0x10,%rdx
  mov    %dl,0x6(%rbx)
  shr    $0x18,%rax
  mov    %al,0x7(%rbx)
  mov    0x30(%rsp),%rax
  mov    %al,0x28(%rbx)
  movzbl %ah,%ecx
  mov    %cl,0x29(%rbx)
  mov    %rax,%rdx
  shr    $0x10,%rdx
  mov    %dl,0x2a(%rbx)
  shr    $0x18,%rax
  mov    %al,0x2b(%rbx)
  mov    %rbp,%rax
L32:
  mov    0x38(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L88
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L88:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
size_t patch_hdr(unsigned char *hdr, size_t hdr_len, unsigned long sec, unsigned long us, unsigned long samples, size_t *data_length_ret) {
  unsigned long chunk_data_length;
  unsigned long format_data_length;
  unsigned long compression_code;
  unsigned long channel_count;
  unsigned long sample_rate;
  unsigned long sample_bit_length;
  unsigned long data_length;
  unsigned long bytes_per_sample;
  if (parse_hdr(hdr, hdr_len, &chunk_data_length, &format_data_length, &compression_code, &channel_count, &sample_rate, &sample_bit_length, &data_length) != hdr_len)
    return 0;
  if (hdr_len != (20 + format_data_length + 8))
    return 0;
  if (format_data_length > 16) {
    memmove(hdr + 20 + 16, hdr + 20 + format_data_length, 8);
    hdr[16] = 16;
    hdr[17] = 0;
    hdr[18] = 0;
    hdr[19] = 0;
    format_data_length = 16;
    hdr_len = 44;
  }
  bytes_per_sample = channel_count * ((sample_bit_length + 7) / 8);
  if (samples == 0) {
    samples = sample_rate * sec;
    samples += ((sample_rate / 100) * (us / 10)) / 1000;
  }
  if (samples > 0) {
    data_length = samples * bytes_per_sample;
    chunk_data_length = data_length + 36;
  } else {
    chunk_data_length = 0xffffffff;
    data_length = chunk_data_length - 36;
  }
  if (data_length_ret != NULL)
    *data_length_ret = data_length;
  hdr[4] = chunk_data_length % 0x100;
  hdr[5] = (chunk_data_length >> 8) % 0x100;
  hdr[6] = (chunk_data_length >> 16) % 0x100;
  hdr[7] = (chunk_data_length >> 24) % 0x100;
  hdr[40] = data_length % 0x100;
  hdr[41] = (data_length >> 8) % 0x100;
  hdr[42] = (data_length >> 16) % 0x100;
  hdr[43] = (data_length >> 24) % 0x100;
  return hdr_len;
}
```