user: 下面的汇编指令对应的C源代码是什么：

```asm
<unbase64>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %esi,-0x2c(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    -0x38(%rbp),%rax
  movl   $0x0,(%rax)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L22
  mov    $0x0,%eax
  jmp    L44
L22:
  mov    -0x2c(%rbp),%eax
  shr    $0x2,%eax
  mov    %eax,%edx
  mov    %edx,%eax
  add    %eax,%eax
  add    %edx,%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x14(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  jne    L87
  mov    $0x0,%eax
  jmp    L44
L87:
  mov    -0x14(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    -0x8(%rbp),%rax
  mov    $0x0,%esi
  mov    %rax,%rdi
  call   <memset@plt>
  mov    -0x8(%rbp),%rax
  mov    %rax,-0x10(%rbp)
L85:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <value@plt>
  mov    %al,-0x18(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <value@plt>
  mov    %al,-0x17(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <value@plt>
  mov    %al,-0x16(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <value@plt>
  mov    %al,-0x15(%rbp)
  movsbl -0x18(%rbp),%eax
  shl    $0x2,%eax
  mov    %eax,%esi
  movzbl -0x17(%rbp),%eax
  sar    $0x4,%al
  mov    %eax,%ecx
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  or     %ecx,%esi
  mov    %esi,%edx
  mov    %dl,(%rax)
  movsbl -0x17(%rbp),%eax
  shl    $0x4,%eax
  mov    %eax,%esi
  movzbl -0x16(%rbp),%eax
  sar    $0x2,%al
  mov    %eax,%ecx
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  or     %ecx,%esi
  mov    %esi,%edx
  mov    %dl,(%rax)
  movsbl -0x16(%rbp),%eax
  shl    $0x6,%eax
  mov    %eax,%ecx
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  or     -0x15(%rbp),%cl
  mov    %ecx,%edx
  mov    %dl,(%rax)
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isbase64@plt>
  test   %eax,%eax
  jne    L134
  subq   $0x2,-0x10(%rbp)
  jmp    L13
L134:
  mov    -0x28(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isbase64@plt>
  test   %eax,%eax
  jne    L68
  subq   $0x2,-0x10(%rbp)
  jmp    L13
L68:
  mov    -0x28(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isbase64@plt>
  test   %eax,%eax
  jne    L80
  subq   $0x1,-0x10(%rbp)
  jmp    L13
L80:
  addq   $0x4,-0x28(%rbp)
  jmp    L136
L57:
  addq   $0x1,-0x28(%rbp)
L136:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L58
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xd,%al
  je     L57
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xa,%al
  je     L57
L58:
  subl   $0x4,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  jne    L85
L13:
  mov    -0x10(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x10(%rbp),%rax
  sub    -0x8(%rbp),%rax
  mov    %eax,%edx
  mov    -0x38(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x8(%rbp),%rax
L44:
  leave
  ret
```

assistant: ```c
char *unbase64(unsigned char *src, unsigned int srclen, unsigned int *len) {
  *len = 0;
  if (*src == 0)
    return NULL;
  unsigned int olen = srclen / 4 * 3;
  char *dest = (char *)malloc(olen + 1);
  if (dest == NULL)
    return NULL;
  memset(dest, 0, olen + 1);
  char *p = dest;
  do {
    char a = value(src[0]);
    char b = value(src[1]);
    char c = value(src[2]);
    char d = value(src[3]);
    *p++ = (a << 2) | (b >> 4);
    *p++ = (b << 4) | (c >> 2);
    *p++ = (c << 6) | d;
    if (!isbase64(src[1])) {
      p -= 2;
      break;
    } else if (!isbase64(src[2])) {
      p -= 2;
      break;
    } else if (!isbase64(src[3])) {
      p--;
      break;
    }
    src += 4;
    while (*src && (*src == 13 || *src == 10))
      src++;
  } while (srclen -= 4);
  *p = 0;
  *len = p - dest;
  return dest;
}
```