user: 请将以下的汇编代码转换成C语言代码:

```asm
<pdu_decode>:
  endbr64
  push   %r15
  mov    %rcx,%r10
  push   %r14
  mov    %esi,%r14d
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x28(%rsp)
  xor    %eax,%eax
  mov    0x78(%rsp),%rcx
  mov    0x80(%rsp),%rsi
  test   %r14d,%r14d
  jle    L1
  movzbl (%rdi),%ebp
  mov    %rcx,0x8(%rsp)
  mov    %rdi,%rbx
  lea    0x1(%rbp),%eax
  cmp    %eax,%r14d
  jle    L25
  cltq
  mov    %rdx,%r15
  movzbl (%rdi,%rax,1),%edx
  lea    0x1(%rdi,%rax,1),%r13
  shr    $0x4,%dl
  movzbl %dl,%edx
  mov    %edx,(%rsi)
  movzbl 0x0(%r13),%esi
  cmp    %r8d,%esi
  jge    L44
  mov    %r10,%rdx
  lea    0x3(%rdi,%rax,1),%rdi
  mov    %r9,%r12
  call   <DecodePhoneNumber@plt>
  movzbl 0x0(%r13),%eax
  add    $0x1,%eax
  sar    %eax
  lea    0x4(%rbp,%rax,1),%r13d
  movslq %r13d,%rbp
  movzbl 0x2(%rbx,%rbp,1),%edi
  call   <SwapDecimalNibble@plt>
  movzbl 0x3(%rbx,%rbp,1),%edi
  add    $0x64,%eax
  mov    %eax,0x10(%rsp)
  call   <SwapDecimalNibble@plt>
  movzbl 0x4(%rbx,%rbp,1),%edi
  sub    $0x1,%eax
  mov    %eax,0x14(%rsp)
  call   <SwapDecimalNibble@plt>
  movzbl 0x5(%rbx,%rbp,1),%edi
  mov    %eax,0x18(%rsp)
  call   <SwapDecimalNibble@plt>
  movzbl 0x6(%rbx,%rbp,1),%edi
  mov    %eax,0x1c(%rsp)
  call   <SwapDecimalNibble@plt>
  movzbl 0x7(%rbx,%rbp,1),%edi
  mov    %eax,0x20(%rsp)
  call   <SwapDecimalNibble@plt>
  movzbl 0x8(%rbx,%rbp,1),%edi
  mov    %eax,0x24(%rsp)
  call   <SwapDecimalNibble@plt>
  lea    0x10(%rsp),%rdi
  mov    %eax,%ebp
  call   <mktime@plt>
  movsbl %bpl,%ebp
  imul   $0x384,%ebp,%ebp
  movslq %ebp,%rbp
  sub    %rbp,%rax
  mov    %rax,(%r15)
  lea    0x9(%r13),%eax
  cmp    %eax,%r14d
  jle    L1
  cltq
  movzbl (%rbx,%rax,1),%r15d
  mov    %r15,%rbp
  cmp    0x70(%rsp),%r15d
  jg     L1
  lea    0x1(%r13),%esi
  mov    0x8(%rsp),%rcx
  movslq %esi,%rsi
  movzbl (%rbx,%rsi,1),%edi
  mov    %edi,(%rcx)
  test   %dil,%dil
  je     L139
  cmp    $0x8,%dil
  je     L37
L93:
  cmp    0x70(%rsp),%r15d
  jl     L75
L90:
  movslq 0x70(%rsp),%r13
  movb   $0x0,-0x1(%r12,%r13,1)
L16:
  mov    0x28(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L61
  add    $0x38,%rsp
  mov    %r15d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   (%rax)
L37:
  lea    0x1(%rbx,%rax,1),%rsi
  mov    %r15d,%edx
  mov    %r12,%rdi
  call   <memcpy@plt>
  cmp    0x70(%rsp),%r15d
  jge    L90
L75:
  movb   $0x0,(%r12,%rbp,1)
  jmp    L16
  cs nopw 0x0(%rax,%rax,1)
L139:
  lea    0xa(%r13),%edx
  mov    %r14d,%esi
  lea    0x1(%rbx,%rax,1),%rdi
  mov    %r15d,%ecx
  sub    %edx,%esi
  mov    %r12,%rdx
  call   <DecodePDUMessage_GSM_7bit@plt>
  cmp    %eax,%r15d
  je     L93
  nopw   0x0(%rax,%rax,1)
L1:
  mov    $0xffffffff,%r15d
  jmp    L16
  nopl   0x0(%rax,%rax,1)
L44:
  mov    $0xfffffffd,%r15d
  jmp    L16
  nopl   0x0(%rax,%rax,1)
L25:
  mov    $0xfffffffe,%r15d
  jmp    L16
L61:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int pdu_decode(const unsigned char *buffer, int buffer_length, time_t *output_sms_time, char *output_sender_phone_number, int sender_phone_number_size, char *output_sms_text, int sms_text_size, int *tp_dcs, int *user_payload_header_size) {
  if (buffer_length <= 0)
    return -1;
  const int sms_deliver_start = 1 + buffer[0];
  if (sms_deliver_start + 1 > buffer_length)
    return -2;
  const int user_data_header_length = (buffer[sms_deliver_start] >> 4);
  *user_payload_header_size = user_data_header_length;
  const int sender_number_length = buffer[sms_deliver_start + 1];
  if (sender_number_length + 1 > sender_phone_number_size)
    return -3;
  DecodePhoneNumber(buffer + sms_deliver_start + 3, sender_number_length, output_sender_phone_number);
  const int sms_pid_start = sms_deliver_start + 3 + (buffer[sms_deliver_start + 1] + 1) / 2;
  struct tm sms_broken_time;
  sms_broken_time.tm_year = 100 + SwapDecimalNibble(buffer[sms_pid_start + 2]);
  sms_broken_time.tm_mon = SwapDecimalNibble(buffer[sms_pid_start + 3]) - 1;
  sms_broken_time.tm_mday = SwapDecimalNibble(buffer[sms_pid_start + 4]);
  sms_broken_time.tm_hour = SwapDecimalNibble(buffer[sms_pid_start + 5]);
  sms_broken_time.tm_min = SwapDecimalNibble(buffer[sms_pid_start + 6]);
  sms_broken_time.tm_sec = SwapDecimalNibble(buffer[sms_pid_start + 7]);
  const char gmt_offset = SwapDecimalNibble(buffer[sms_pid_start + 8]);
  (*output_sms_time) = mktime(&sms_broken_time) - gmt_offset * 15 * 60;
  const int sms_start = sms_pid_start + 2 + 7;
  if (sms_start + 1 > buffer_length)
    return -1;
  const int output_sms_text_length = buffer[sms_start];
  if (sms_text_size < output_sms_text_length)
    return -1;
  const int sms_tp_dcs_start = sms_pid_start + 1;
  *tp_dcs = buffer[sms_tp_dcs_start];
  switch (*tp_dcs) {
  case 0: {
    int decoded_sms_text_size = DecodePDUMessage_GSM_7bit(buffer + sms_start + 1, buffer_length - (sms_start + 1), output_sms_text, output_sms_text_length);
    if (decoded_sms_text_size != output_sms_text_length)
      return -1;
    break;
  }
  case 8: {
    memcpy(output_sms_text, buffer + sms_start + 1, output_sms_text_length);
    break;
  }
  default:
    break;
  }
  if (output_sms_text_length < sms_text_size)
    output_sms_text[output_sms_text_length] = 0;
  else
    output_sms_text[sms_text_size - 1] = 0;
  return output_sms_text_length;
}
```