user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<channel_encode>:
  endbr64
  push   %r15
  lea    -0x10(%rdx),%rax
  mov    %rsi,%r15
  push   %r14
  push   %r13
  mov    %rdx,%r13
  push   %r12
  mov    %rdi,%r12
  push   %rbp
  push   %rbx
  mov    %rdx,%rbx
  and    $0x7,%ebx
  sub    $0x28,%rsp
  shr    $0x3,%rax
  mov    %ecx,0x14(%rsp)
  mov    %r8,0x8(%rsp)
  mov    %rax,0x18(%rsp)
  je     L6
  mov    %rdi,%r14
  lea    (%rdi,%rax,8),%rbp
  mov    $0xffff,%edi
  nopl   0x0(%rax)
L41:
  mov    (%r14),%rsi
  add    $0x8,%r14
  call   <crc_xmodem_update@plt>
  mov    %rax,%rdi
  cmp    %r14,%rbp
  jne    L41
L144:
  mov    0x18(%rsp),%rdx
  shl    $0x3,%rdx
  lea    (%r12,%rdx,1),%rbp
  test   %rbx,%rbx
  je     L14
  xor    %esi,%esi
  xor    %eax,%eax
  nopw   0x0(%rax,%rax,1)
L71:
  shr    %rsi
  add    $0x1,%rax
  or     $0x80,%sil
  cmp    %rax,%rbx
  jne    L71
  and    0x0(%rbp),%rsi
  mov    %rdx,0x18(%rsp)
  call   <crc_xmodem_update@plt>
  mov    0x18(%rsp),%rdx
  mov    %rax,%rdi
L14:
  mov    $0x7,%ecx
  movq   $0x0,0x0(%rbp)
  mov    $0x1,%eax
  movq   $0x0,0x8(%r12,%rdx,1)
  sub    %ebx,%ecx
  shl    %cl,%eax
  mov    $0x10,%ecx
  cltq
  nopl   0x0(%rax)
L48:
  test   $0x8000,%edi
  je     L129
  or     %rax,0x0(%rbp)
L129:
  add    %rdi,%rdi
  shr    %rax
  jne    L73
  add    $0x8,%rbp
  mov    $0x80,%eax
L73:
  sub    $0x1,%rcx
  jne    L48
  movq   $0x55,(%r15)
  mov    $0x9a52e716,%edx
  mov    $0x7,%eax
  movq   $0x55,0x8(%r15)
  movq   $0x55,0x10(%r15)
  movq   $0x55,0x18(%r15)
L67:
  movzbl %dl,%esi
  sar    $0x8,%edx
  mov    %rsi,(%r15,%rax,8)
  sub    $0x1,%rax
  cmp    $0x3,%rax
  jne    L67
  mov    0x14(%rsp),%edx
  mov    0x8(%rsp),%rax
  sar    $0x11,%edx
  and    $0x3,%eax
  and    $0xfc,%edx
  or     %rax,%rdx
  mov    %rdx,%rax
  shl    $0x4,%rax
  and    $0xf00,%eax
  or     %rdx,%rax
  and    $0xf0f,%eax
  mov    %rax,%rdx
  mov    %rax,%rsi
  mov    %rax,%rdi
  shr    $0x2,%rdx
  shr    %rsi
  xor    %rdx,%rsi
  shr    $0x3,%rdi
  and    $0x1,%esi
  and    $0x1,%edi
  cmp    %sil,%dil
  je     L169
  or     $0x10,%rax
  mov    %rax,%rsi
  mov    %rax,%rdx
  shr    $0x3,%rsi
  shr    $0x2,%rdx
  and    $0x1,%esi
L169:
  xor    %rax,%rdx
  and    $0x1,%edx
  cmp    %dl,%sil
  je     L131
  or     $0x20,%rax
  mov    %rax,%rdx
  shr    $0x3,%rdx
  and    $0x1,%edx
L131:
  mov    %rax,%rsi
  shr    %rsi
  xor    %rax,%rsi
  and    $0x1,%esi
  cmp    %dl,%sil
  je     L173
  or     $0x40,%rax
  mov    %rax,%rdx
  shr    %rdx
  xor    %rax,%rdx
  and    $0x1,%edx
L173:
  mov    %rax,%rsi
  mov    %rax,%rdi
  mov    $0x80,%r8d
  shr    $0x2,%rsi
  or     $0x80,%dil
  and    $0x1,%esi
  cmp    %dl,%sil
  mov    $0x80,%edx
  cmovne %rdi,%rax
  xor    %esi,%esi
  jmp    L187
  nopl   0x0(%rax)
L94:
  lea    -0x7(%rcx),%rdi
  sub    $0xf,%rcx
  cmp    $0x7,%rdi
  cmovbe %rdi,%rcx
  add    $0x1,%rsi
  cmp    $0x10,%rsi
  je     L118
L187:
  bt     %rcx,%rax
  jae    L155
  mov    %rsi,%rdi
  shr    $0x3,%rdi
  or     %rdx,0x40(%r15,%rdi,8)
L155:
  shr    %rdx
  lea    0x8(%rcx),%rdi
  cmove  %r8,%rdx
  cmp    $0xf,%rdi
  ja     L94
  add    $0x1,%rsi
  mov    %rdi,%rcx
  cmp    $0x10,%rsi
  jne    L187
L118:
  lea    0x4(%r13),%rbp
  mov    0x14(%rsp),%r8d
  lea    0x50(%r15),%rsi
  mov    %r13,%rcx
  mov    %rbp,%rax
  mov    %rbp,%rbx
  mov    %r12,%rdi
  and    $0x7,%eax
  shr    $0x3,%rbx
  cmp    $0x1,%rax
  sbb    $0xfffffffffffffff4,%rbx
  shl    $0x3,%rbx
  lea    (%r15,%rbx,1),%rdx
  call   <encode_turbo@plt>
  cmpq   $0x0,0x8(%rsp)
  jne    L37
  add    $0x28,%rsp
  shr    $0x2,%rbp
  lea    0x0(%rbp,%rbx,1),%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L37:
  cmpq   $0x1,0x8(%rsp)
  je     L79
  lea    0x0(%rbp,%rbx,1),%rdx
  lea    (%rbx,%rbp,2),%rax
  cmpq   $0x2,0x8(%rsp)
  cmove  %rdx,%rax
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L79:
  lea    0x0(,%r13,8),%rdx
  add    $0x28,%rsp
  movabs $0x4ec4ec4ec4ec4ec5,%rcx
  sub    %r13,%rdx
  add    $0x1c,%rdx
  mov    %rdx,%rax
  mul    %rcx
  shr    $0x2,%rdx
  lea    (%rdx,%rbx,1),%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L6:
  mov    $0xffff,%edi
  jmp    L144
```

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;
}
```