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

```asm
<decode_quoted_printable>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %esi,-0x4c(%rbp)
  mov    %rdx,-0x58(%rbp)
  mov    %ecx,-0x50(%rbp)
  mov    -0x58(%rbp),%rax
  mov    (%rax),%eax
  mov    %eax,-0x34(%rbp)
  mov    -0x58(%rbp),%rax
  movl   $0x0,(%rax)
  cmpl   $0x0,-0x4c(%rbp)
  jne    L733
  mov    $0x0,%eax
  jmp    L477
L733:
  mov    -0x4c(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,-0x30(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  jne    L300
  mov    $0x0,%eax
  jmp    L477
L300:
  mov    -0x30(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  cmpl   $0x0,-0x50(%rbp)
  je     L312
  movl   $0x0,-0x38(%rbp)
  jmp    L73
L25:
  mov    -0x48(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x3c(%rbp)
  cmpb   $0x3d,-0x3c(%rbp)
  jne    L191
  mov    -0x48(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x3c(%rbp)
  mov    -0x48(%rbp),%rax
  movzbl 0x1(%rax),%eax
  mov    %al,-0x39(%rbp)
  cmpb   $0x2f,-0x3c(%rbp)
  jbe    L5
  cmpb   $0x39,-0x3c(%rbp)
  jbe    L253
L5:
  cmpb   $0x40,-0x3c(%rbp)
  jbe    L36
  cmpb   $0x46,-0x3c(%rbp)
  jbe    L253
L36:
  cmpb   $0x60,-0x3c(%rbp)
  jbe    L340
  cmpb   $0x66,-0x3c(%rbp)
  ja     L340
L253:
  cmpb   $0x2f,-0x39(%rbp)
  jbe    L283
  cmpb   $0x39,-0x39(%rbp)
  jbe    L734
L283:
  cmpb   $0x40,-0x39(%rbp)
  jbe    L114
  cmpb   $0x46,-0x39(%rbp)
  jbe    L734
L114:
  cmpb   $0x60,-0x39(%rbp)
  jbe    L340
  cmpb   $0x66,-0x39(%rbp)
  ja     L340
L734:
  movzbl -0x3c(%rbp),%eax
  cmpb   $0x39,-0x3c(%rbp)
  jbe    L124
  cmpb   $0x46,-0x3c(%rbp)
  jbe    L584
  mov    $0x57,%edx
  jmp    L55
L584:
  mov    $0x37,%edx
  jmp    L55
L124:
  mov    $0x30,%edx
L55:
  sub    %edx,%eax
  shl    $0x4,%eax
  mov    %eax,%ecx
  cmpb   $0x39,-0x39(%rbp)
  jbe    L66
  cmpb   $0x46,-0x39(%rbp)
  jbe    L63
  mov    $0x57,%edx
  jmp    L735
L63:
  mov    $0x37,%edx
  jmp    L735
L66:
  mov    $0x30,%edx
L735:
  movzbl -0x39(%rbp),%eax
  sub    %edx,%eax
  or     %ecx,%eax
  mov    %al,-0x3c(%rbp)
  cmpl   $0x0,-0x4c(%rbp)
  je     L166
  subl   $0x1,-0x4c(%rbp)
L166:
  cmpl   $0x0,-0x4c(%rbp)
  je     L207
  subl   $0x1,-0x4c(%rbp)
L207:
  addq   $0x2,-0x48(%rbp)
  jmp    L698
L340:
  movb   $0x3d,-0x3c(%rbp)
  jmp    L698
L191:
  cmpb   $0x5f,-0x3c(%rbp)
  jne    L698
  movb   $0x20,-0x3c(%rbp)
L698:
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x30(%rbp)
  movzbl -0x3c(%rbp),%edx
  mov    %dl,(%rax)
  addl   $0x1,-0x38(%rbp)
  mov    -0x38(%rbp),%eax
  cmp    -0x34(%rbp),%eax
  jae    L590
L73:
  mov    -0x4c(%rbp),%eax
  lea    -0x1(%rax),%edx
  mov    %edx,-0x4c(%rbp)
  test   %eax,%eax
  jne    L25
  jmp    L563
L590:
  nop
L563:
  mov    -0x30(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x30(%rbp),%rax
  sub    -0x10(%rbp),%rax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x58(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%edx
  mov    -0x10(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <realloc@plt>
  jmp    L477
L312:
  mov    -0x4c(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,-0x28(%rbp)
  cmpq   $0x0,-0x28(%rbp)
  jne    L480
  mov    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    $0x0,%eax
  jmp    L477
L480:
  mov    -0x4c(%rbp),%edx
  mov    -0x48(%rbp),%rcx
  mov    -0x28(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <memcpy@plt>
  mov    -0x4c(%rbp),%edx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movb   $0x0,(%rax)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  jmp    L221
L412:
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x20(%rbp),%rax
  mov    $0xa,%esi
  mov    %rax,%rdi
  call   <strchr@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L725
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x28(%rbp)
  subq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jb     L726
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xd,%al
  jne    L726
  subq   $0x1,-0x18(%rbp)
  jmp    L726
L725:
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  cltq
  lea    -0x1(%rax),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x18(%rbp)
  movq   $0x0,-0x28(%rbp)
  jmp    L726
L409:
  subq   $0x1,-0x18(%rbp)
L726:
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jb     L764
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x3b(%rbp)
  cmpb   $0x20,-0x3b(%rbp)
  je     L409
  cmpb   $0x9,-0x3b(%rbp)
  je     L409
L764:
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movb   $0x0,(%rax)
L236:
  mov    -0x20(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x20(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x3b(%rbp)
  movzbl -0x3b(%rbp),%eax
  test   %eax,%eax
  je     L661
  cmp    $0x3d,%eax
  je     L586
  jmp    L489
L661:
  cmpq   $0x0,-0x28(%rbp)
  je     L496
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x30(%rbp)
  movb   $0xa,(%rax)
  jmp    L496
L586:
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x3b(%rbp)
  cmpb   $0x0,-0x3b(%rbp)
  je     L104
  mov    -0x20(%rbp),%rax
  movzbl 0x1(%rax),%eax
  mov    %al,-0x3a(%rbp)
  cmpb   $0x2f,-0x3b(%rbp)
  jbe    L447
  cmpb   $0x39,-0x3b(%rbp)
  jbe    L317
L447:
  cmpb   $0x40,-0x3b(%rbp)
  jbe    L99
  cmpb   $0x46,-0x3b(%rbp)
  jbe    L317
L99:
  cmpb   $0x60,-0x3b(%rbp)
  jbe    L599
  cmpb   $0x66,-0x3b(%rbp)
  ja     L599
L317:
  cmpb   $0x2f,-0x3a(%rbp)
  jbe    L593
  cmpb   $0x39,-0x3a(%rbp)
  jbe    L549
L593:
  cmpb   $0x40,-0x3a(%rbp)
  jbe    L256
  cmpb   $0x46,-0x3a(%rbp)
  jbe    L549
L256:
  cmpb   $0x60,-0x3a(%rbp)
  jbe    L599
  cmpb   $0x66,-0x3a(%rbp)
  ja     L599
L549:
  movzbl -0x3b(%rbp),%eax
  cmpb   $0x39,-0x3b(%rbp)
  jbe    L730
  cmpb   $0x46,-0x3b(%rbp)
  jbe    L509
  mov    $0x57,%edx
  jmp    L314
L509:
  mov    $0x37,%edx
  jmp    L314
L730:
  mov    $0x30,%edx
L314:
  sub    %edx,%eax
  shl    $0x4,%eax
  mov    %eax,%ecx
  cmpb   $0x39,-0x3a(%rbp)
  jbe    L768
  cmpb   $0x46,-0x3a(%rbp)
  jbe    L721
  mov    $0x57,%edx
  jmp    L38
L721:
  mov    $0x37,%edx
  jmp    L38
L768:
  mov    $0x30,%edx
L38:
  movzbl -0x3a(%rbp),%eax
  sub    %edx,%eax
  or     %eax,%ecx
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x30(%rbp)
  mov    %ecx,%edx
  mov    %dl,(%rax)
  addq   $0x2,-0x20(%rbp)
  jmp    L104
L599:
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x30(%rbp)
  movb   $0x3d,(%rax)
  jmp    L104
L489:
  mov    -0x30(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x30(%rbp)
  movzbl -0x3b(%rbp),%edx
  mov    %dl,(%rax)
  jmp    L238
L496:
  nop
  jmp    L238
L104:
  nop
L238:
  mov    -0x30(%rbp),%rax
  sub    -0x10(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x34(%rbp),%eax
  cmp    %rax,%rdx
  jl     L23
  movq   $0x0,-0x28(%rbp)
  jmp    L221
L23:
  cmpb   $0x0,-0x3b(%rbp)
  jne    L236
L221:
  cmpq   $0x0,-0x28(%rbp)
  jne    L412
  mov    -0x30(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x8(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x30(%rbp),%rax
  sub    -0x10(%rbp),%rax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x58(%rbp),%rax
  mov    (%rax),%eax
  lea    0x1(%rax),%edx
  mov    -0x10(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <realloc@plt>
L477:
  leave
  ret
```

assistant: ```c
char *decode_quoted_printable(unsigned char *buf, unsigned int len, unsigned int *ret_len, int header) {
  unsigned char *dest, *deststart;
  unsigned int limit = *ret_len;
  *ret_len = 0;
  if (!len)
    return NULL;
  if (!(dest = (unsigned char *)malloc(len + 1)))
    return NULL;
  deststart = dest;
  if (header) {
    unsigned int real_len = 0;
    while (len--) {
      unsigned char c = *buf++;
      if ('=' == c) {
        unsigned char c2;
        c = buf[0];
        c2 = buf[1];
        if (((((c) >= '0') && ((c) <= '9')) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f'))) && ((((c2) >= '0') && ((c2) <= '9')) || (((c2) >= 'A') && ((c2) <= 'F')) || (((c2) >= 'a') && ((c2) <= 'f')))) {
          c = (((c) - (((c) > '9') ? (((c) > 'F') ? 'a' - 10 : 'A' - 10) : '0')) << 4) | ((c2) - (((c2) > '9') ? (((c2) > 'F') ? 'a' - 10 : 'A' - 10) : '0'));
          if (len)
            len--;
          if (len)
            len--;
          buf += 2;
        } else
          c = '=';
      } else if ('_' == c)
        c = ' ';
      *dest++ = c;
      if (++real_len >= limit)
        break;
    }
    *dest = 0;
    *ret_len = dest - deststart;
    return (char *)realloc(deststart, *ret_len + 1);
  } else {
    unsigned char *text, *textstart;
    if (!(text = (unsigned char *)malloc(len + 1))) {
      free(dest);
      return NULL;
    }
    memcpy(text, buf, len);
    text[len] = 0;
    textstart = text;
    while (text) {
      unsigned char c;
      unsigned char *lp = text;
      {
        unsigned char *ep;
        if ((ep = (unsigned char *)strchr((char *)lp, '\n'))) {
          text = ep + 1;
          ep--;
          if (ep >= lp) {
            if ('\r' == *ep)
              ep--;
          }
        } else {
          ep = lp + strlen((char *)lp) - 1;
          text = NULL;
        }
        while ((ep >= lp) && (((c = *ep) == ' ') || (c == '\t')))
          ep--;
        *(ep + 1) = '\0';
      }
      do {
        switch (c = *lp++) {
        case '\0':
          if (text)
            *dest++ = '\n';
          break;
        case '=':
          if ((c = *lp)) {
            unsigned char d = *(lp + 1);
            if (((((c) >= '0') && ((c) <= '9')) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f'))) && ((((d) >= '0') && ((d) <= '9')) || (((d) >= 'A') && ((d) <= 'F')) || (((d) >= 'a') && ((d) <= 'f')))) {
              *dest++ = (((c) - (((c) > '9') ? (((c) > 'F') ? 'a' - 10 : 'A' - 10) : '0')) << 4) | ((d) - (((d) > '9') ? (((d) > 'F') ? 'a' - 10 : 'A' - 10) : '0'));
              lp += 2;
            } else {
              *dest++ = '=';
            }
          }
          break;
        default:
          *dest++ = c;
          break;
        }
        if ((dest - deststart) >= limit) {
          text = NULL;
          break;
        }
      } while (c);
    }
    *dest = 0;
    free(textstart);
    *ret_len = dest - deststart;
    return (char *)realloc(deststart, *ret_len + 1);
  }
}
```