user: 请从给定的汇编指令推导出C源代码:

```asm
<pdu_decode>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x90,%rsp
  mov    %rdi,-0x58(%rbp)
  mov    %esi,-0x5c(%rbp)
  mov    %rdx,-0x68(%rbp)
  mov    %rcx,-0x70(%rbp)
  mov    %r8d,-0x60(%rbp)
  mov    %r9,-0x78(%rbp)
  mov    0x18(%rbp),%rax
  mov    %rax,-0x80(%rbp)
  mov    0x20(%rbp),%rax
  mov    %rax,-0x88(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  cmpl   $0x0,-0x5c(%rbp)
  jg     L132
  mov    $0xffffffff,%eax
  jmp    L179
L132:
  mov    -0x58(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    $0x1,%eax
  mov    %eax,-0x40(%rbp)
  mov    -0x40(%rbp),%eax
  cmp    -0x5c(%rbp),%eax
  jl     L7
  mov    $0xfffffffe,%eax
  jmp    L179
L7:
  mov    -0x40(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  shr    $0x4,%al
  movzbl %al,%eax
  mov    %eax,-0x3c(%rbp)
  mov    -0x88(%rbp),%rax
  mov    -0x3c(%rbp),%edx
  mov    %edx,(%rax)
  mov    -0x40(%rbp),%eax
  cltq
  lea    0x1(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,-0x38(%rbp)
  mov    -0x38(%rbp),%eax
  cmp    -0x60(%rbp),%eax
  jl     L28
  mov    $0xfffffffd,%eax
  jmp    L179
L28:
  mov    -0x40(%rbp),%eax
  cltq
  lea    0x3(%rax),%rdx
  mov    -0x58(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x70(%rbp),%rdx
  mov    -0x38(%rbp),%eax
  mov    %eax,%esi
  mov    %rcx,%rdi
  call   <DecodePhoneNumber@plt>
  mov    -0x40(%rbp),%eax
  lea    0x3(%rax),%edx
  mov    -0x40(%rbp),%eax
  cltq
  lea    0x1(%rax),%rcx
  mov    -0x58(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  add    $0x1,%eax
  mov    %eax,%ecx
  shr    $0x1f,%ecx
  add    %ecx,%eax
  sar    %eax
  add    %edx,%eax
  mov    %eax,-0x34(%rbp)
  mov    -0x34(%rbp),%eax
  cltq
  lea    0x2(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <SwapDecimalNibble@plt>
  add    $0x64,%eax
  mov    %eax,-0x20(%rbp)
  mov    -0x34(%rbp),%eax
  cltq
  lea    0x3(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <SwapDecimalNibble@plt>
  sub    $0x1,%eax
  mov    %eax,-0x1c(%rbp)
  mov    -0x34(%rbp),%eax
  cltq
  lea    0x4(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <SwapDecimalNibble@plt>
  mov    %eax,-0x18(%rbp)
  mov    -0x34(%rbp),%eax
  cltq
  lea    0x5(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <SwapDecimalNibble@plt>
  mov    %eax,-0x14(%rbp)
  mov    -0x34(%rbp),%eax
  cltq
  lea    0x6(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <SwapDecimalNibble@plt>
  mov    %eax,-0x10(%rbp)
  mov    -0x34(%rbp),%eax
  cltq
  lea    0x7(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <SwapDecimalNibble@plt>
  mov    %eax,-0xc(%rbp)
  mov    -0x34(%rbp),%eax
  cltq
  lea    0x8(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <SwapDecimalNibble@plt>
  mov    %al,-0x41(%rbp)
  lea    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <mktime@plt>
  movsbl -0x41(%rbp),%edx
  imul   $0x384,%edx,%edx
  movslq %edx,%rcx
  sub    %rcx,%rax
  mov    %rax,%rdx
  mov    -0x68(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x34(%rbp),%eax
  add    $0x9,%eax
  mov    %eax,-0x30(%rbp)
  mov    -0x30(%rbp),%eax
  cmp    -0x5c(%rbp),%eax
  jl     L178
  mov    $0xffffffff,%eax
  jmp    L179
L178:
  mov    -0x30(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,-0x2c(%rbp)
  mov    0x10(%rbp),%eax
  cmp    -0x2c(%rbp),%eax
  jge    L106
  mov    $0xffffffff,%eax
  jmp    L179
L106:
  mov    -0x34(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%edx
  mov    -0x80(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x80(%rbp),%rax
  mov    (%rax),%eax
  test   %eax,%eax
  je     L147
  cmp    $0x8,%eax
  je     L80
  jmp    L164
L147:
  mov    -0x30(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    -0x5c(%rbp),%eax
  sub    %edx,%eax
  mov    %eax,%esi
  mov    -0x30(%rbp),%eax
  cltq
  lea    0x1(%rax),%rdx
  mov    -0x58(%rbp),%rax
  lea    (%rdx,%rax,1),%rdi
  mov    -0x2c(%rbp),%edx
  mov    -0x78(%rbp),%rax
  mov    %edx,%ecx
  mov    %rax,%rdx
  call   <DecodePDUMessage_GSM_7bit@plt>
  mov    %eax,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  cmp    -0x2c(%rbp),%eax
  je     L15
  mov    $0xffffffff,%eax
  jmp    L179
L80:
  mov    -0x30(%rbp),%eax
  cltq
  lea    0x1(%rax),%rdx
  mov    -0x58(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x2c(%rbp),%edx
  mov    -0x78(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  jmp    L164
L15:
  nop
L164:
  mov    -0x2c(%rbp),%eax
  cmp    0x10(%rbp),%eax
  jge    L62
  mov    -0x2c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x78(%rbp),%rax
  add    %rdx,%rax
  movb   $0x0,(%rax)
  jmp    L44
L62:
  mov    0x10(%rbp),%eax
  cltq
  lea    -0x1(%rax),%rdx
  mov    -0x78(%rbp),%rax
  add    %rdx,%rax
  movb   $0x0,(%rax)
L44:
  mov    -0x2c(%rbp),%eax
L179:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L77
  call   <__stack_chk_fail@plt>
L77:
  leave
  ret
```

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