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

```asm
<channel_encode>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,%r14
  mov    %rsi,%rbp
  mov    %rdx,%r15
  mov    %ecx,0x14(%rsp)
  mov    %r8,0x8(%rsp)
  lea    -0x10(%rdx),%rax
  mov    %rdx,%r12
  and    $0x7,%r12d
  shr    $0x3,%rax
  mov    %rax,0x18(%rsp)
  je     L107
  mov    %rdi,%rbx
  lea    (%rdi,%rax,8),%r13
  mov    $0xffff,%edi
L100:
  mov    (%rbx),%rsi
  call   <crc_xmodem_update@plt>
  mov    %rax,%rdi
  add    $0x8,%rbx
  cmp    %rbx,%r13
  jne    L100
L52:
  test   %r12,%r12
  je     L153
  mov    $0x0,%esi
  mov    $0x0,%eax
L23:
  shr    %rsi
  or     $0x80,%sil
  add    $0x1,%rax
  cmp    %rax,%r12
  jne    L23
  mov    0x18(%rsp),%rax
  and    (%r14,%rax,8),%rsi
  call   <crc_xmodem_update@plt>
  mov    %rax,%rdi
L153:
  mov    $0x7,%ecx
  sub    %r12d,%ecx
  mov    $0x1,%edx
  shl    %cl,%edx
  movslq %edx,%rdx
  mov    0x18(%rsp),%rax
  shl    $0x3,%rax
  lea    (%r14,%rax,1),%rcx
  movq   $0x0,(%rcx)
  movq   $0x0,0x8(%r14,%rax,1)
  mov    $0x10,%eax
  jmp    L159
L107:
  mov    $0xffff,%edi
  jmp    L52
L73:
  sub    $0x1,%rax
  je     L186
L159:
  test   $0x8000,%edi
  je     L150
  or     %rdx,(%rcx)
L150:
  add    %rdi,%rdi
  shr    %rdx
  jne    L73
  add    $0x8,%rcx
  mov    $0x80,%edx
  jmp    L73
L186:
  movq   $0x55,0x0(%rbp)
  movq   $0x55,0x8(%rbp)
  movq   $0x55,0x10(%rbp)
  movq   $0x55,0x18(%rbp)
  mov    $0x9a52e716,%ecx
  mov    $0x7,%edx
L44:
  movzbl %cl,%esi
  mov    %rsi,0x0(%rbp,%rdx,8)
  sar    $0x8,%ecx
  sub    $0x1,%rdx
  cmp    $0x3,%rdx
  jne    L44
  mov    0x14(%rsp),%edx
  sar    $0x11,%edx
  and    $0xfc,%edx
  mov    0x8(%rsp),%rcx
  and    $0x3,%ecx
  or     %rcx,%rdx
  mov    %rdx,%rsi
  shl    $0x4,%rsi
  and    $0xf00,%esi
  or     %rdx,%rsi
  and    $0xf0f,%esi
  mov    %rsi,%rcx
  shr    $0x3,%rcx
  and    $0x1,%ecx
  mov    %rsi,%rdi
  shr    %rdi
  mov    %rsi,%rdx
  shr    $0x2,%rdx
  xor    %edi,%edx
  and    $0x1,%edx
  mov    %rsi,%rdi
  or     $0x10,%rdi
  cmp    %dl,%cl
  cmovne %rdi,%rsi
  mov    %rsi,%rcx
  shr    $0x3,%rcx
  and    $0x1,%ecx
  mov    %rsi,%rdx
  shr    $0x2,%rdx
  xor    %esi,%edx
  and    $0x1,%edx
  mov    %rsi,%rdi
  or     $0x20,%rdi
  cmp    %dl,%cl
  cmovne %rdi,%rsi
  mov    %rsi,%rcx
  shr    $0x3,%rcx
  and    $0x1,%ecx
  mov    %rsi,%rdx
  shr    %rdx
  xor    %esi,%edx
  and    $0x1,%edx
  mov    %rsi,%rdi
  or     $0x40,%rdi
  cmp    %dl,%cl
  cmovne %rdi,%rsi
  mov    %rsi,%rcx
  shr    $0x2,%rcx
  and    $0x1,%ecx
  mov    %rsi,%rdx
  shr    %rdx
  xor    %esi,%edx
  and    $0x1,%edx
  mov    %rsi,%rdi
  or     $0x80,%dil
  cmp    %dl,%cl
  cmovne %rdi,%rsi
  mov    %rax,%rcx
  mov    $0x80,%edx
  mov    $0x80,%r8d
  jmp    L147
L149:
  mov    %rdi,%rcx
L191:
  add    $0x1,%rax
  cmp    $0x10,%rax
  je     L151
L147:
  bt     %rcx,%rsi
  jae    L123
  mov    %rax,%rdi
  shr    $0x3,%rdi
  or     %rdx,0x40(%rbp,%rdi,8)
L123:
  shr    %rdx
  cmove  %r8,%rdx
  lea    0x8(%rcx),%rdi
  cmp    $0xf,%rdi
  jbe    L149
  lea    -0x7(%rcx),%rdi
  sub    $0xf,%rcx
  cmp    $0x7,%rdi
  cmovbe %rdi,%rcx
  jmp    L191
L151:
  lea    0x4(%r15),%rbx
  mov    %rbx,%rax
  shr    $0x3,%rax
  mov    %rbx,%rdx
  and    $0x7,%edx
  cmp    $0x1,%rdx
  sbb    $0xfffffffffffffff4,%rax
  lea    0x0(,%rax,8),%r12
  lea    0x0(%rbp,%r12,1),%rdx
  lea    0x50(%rbp),%rsi
  mov    0x14(%rsp),%r8d
  mov    %r15,%rcx
  mov    %r14,%rdi
  call   <encode_turbo@plt>
  cmpq   $0x0,0x8(%rsp)
  jne    L137
  shr    $0x2,%rbx
  lea    (%rbx,%r12,1),%rax
L75:
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L137:
  cmpq   $0x1,0x8(%rsp)
  je     L5
  lea    (%rbx,%r12,1),%rdx
  lea    (%r12,%rbx,2),%rax
  cmpq   $0x2,0x8(%rsp)
  cmove  %rdx,%rax
  jmp    L75
L5:
  lea    0x0(,%r15,8),%rdx
  sub    %r15,%rdx
  add    $0x1c,%rdx
  movabs $0x4ec4ec4ec4ec4ec5,%rcx
  mov    %rdx,%rax
  mul    %rcx
  shr    $0x2,%rdx
  lea    (%rdx,%r12,1),%rax
  jmp    L75
```

assistant: ```c
uint16_t channel_encode(uint8_t *input, uint8_t *output, uint16_t interleaver_len, uint32_t int_coeff, uint8_t rate) {
  uint16_t full_bytes = (interleaver_len - 16) >> 3;
  uint8_t remaining_bits = (interleaver_len - 16) & 0x7;
  uint16_t crc = 0xFFFF;
  uint8_t i;
  for (i = 0; i < full_bytes; i++)
    crc = crc_xmodem_update(crc, input[i]);
  uint8_t mask = 0;
  for (i = 0; i < remaining_bits; i++)
    mask = (mask >> 1) | 0x80;
  if (mask > 0)
    crc = crc_xmodem_update(crc, mask & input[full_bytes]);
  mask = 1 << (7 - remaining_bits);
  uint8_t *ptr = &input[full_bytes];
  input[full_bytes] = 0;
  input[full_bytes + 1] = 0;
  for (i = 0; i < 16; i++) {
    if (crc & 0x8000)
      *ptr |= mask;
    crc <<= 1;
    mask >>= 1;
    if (mask == 0) {
      mask = 0x80;
      ptr++;
    }
  }
  for (i = 0; i < 4; i++)
    output[i] = 0x55;
  uint32_t sync = 0x9A52E716;
  for (i = 4 + 4 - 1; i >= 4; i--) {
    output[i] = sync & 0xFF;
    sync >>= 8;
  }
  uint16_t size_f = ((int_coeff >> 17) & 0xFC) | (uint16_t)(rate & 0x3);
  size_f |= (size_f << 4) & 0xF00;
  size_f &= 0xF0F;
  for (i = 0; i < 2 * 4; i += 8) {
    if (((size_f & ((uint16_t)1 << (i + 1))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 2))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 3))) > 0))
      size_f |= ((uint16_t)1 << (i + 4));
    if (((size_f & ((uint16_t)1 << (i + 0))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 2))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 3))) > 0))
      size_f |= ((uint16_t)1 << (i + 5));
    if (((size_f & ((uint16_t)1 << (i + 0))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 1))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 3))) > 0))
      size_f |= ((uint16_t)1 << (i + 6));
    if (((size_f & ((uint16_t)1 << (i + 0))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 1))) > 0) ^ ((size_f & ((uint16_t)1 << (i + 2))) > 0))
      size_f |= ((uint16_t)1 << (i + 7));
  }
  uint8_t addr = 0;
  mask = 0x80;
  for (i = 0; i < 16; i++) {
    if (size_f & (uint16_t)1 << (addr))
      output[4 + 4 + (i >> 3)] |= mask;
    mask >>= 1;
    if (mask == 0)
      mask = 0x80;
    addr = addr + 8;
    if (addr > 15) {
      addr = addr - 16;
      addr += 1;
      if (addr >= 8)
        addr -= 8;
    }
  }
  full_bytes = (interleaver_len + 4) >> 3;
  remaining_bits = (interleaver_len + 4) & 0x7;
  if (remaining_bits > 0)
    full_bytes++;
  encode_turbo(input, &output[4 + 4 + 2], &output[4 + 4 + 2 + full_bytes + 1], interleaver_len, int_coeff);
  size_f = 4 * 8 + 4 * 8 + 2 * 8 + 8 * full_bytes + 1 * 8;
  if (rate == 0)
    size_f += (interleaver_len + 4) >> 2;
  else if (rate == 1)
    size_f += ((interleaver_len + 4) * 7) / 13;
  else if (rate == 2)
    size_f += (interleaver_len + 4);
  else
    size_f += 2 * (interleaver_len + 4);
  return size_f;
}
```