user: Please show me the C implementation that matches the assembly code listed below:

```asm
<base64_decode>:
  endbr64
  push   %r15
  push   %r14
  mov    %rdi,%r14
  push   %r13
  push   %r12
  mov    %rsi,%r12
  push   %rbp
  push   %rbx
  mov    %rdx,%rbx
  sub    $0x8,%rsp
  call   <strlen@plt>
  lea    0x1(%rax),%edi
  call   <malloc@plt>
  mov    %r14,%rdi
  mov    %rax,%rbp
  call   <strlen@plt>
  mov    %r14,%rdi
  mov    %rbp,%r15
  mov    %eax,%r13d
  call   <strlen@plt>
  xor    %esi,%esi
  mov    %rbp,%rdi
  lea    0x1(%rax),%edx
  call   <memset@plt>
  movsbl (%r14),%esi
  lea    D23(%rip),%rdx
  test   %sil,%sil
  jne    L237
  jmp    L95
  nopl   0x0(%rax,%rax,1)
L222:
  mov    %al,(%r15)
L179:
  movsbl 0x1(%r14),%esi
  add    $0x1,%r14
  add    $0x1,%r15
  test   %sil,%sil
  je     L95
L237:
  lea    -0x41(%rsi),%eax
  cmp    $0x19,%al
  jbe    L222
  cmp    $0x39,%sil
  jg     L40
  cmp    $0x2f,%sil
  jg     L38
  cmp    $0x2b,%sil
  je     L148
  cmp    $0x2f,%sil
  jne    L42
  movb   $0x3f,(%r15)
  jmp    L179
  nopw   0x0(%rax,%rax,1)
L40:
  cmp    $0x3d,%sil
  je     L35
  lea    -0x61(%rsi),%eax
  cmp    $0x19,%al
  jbe    L15
L42:
  mov    %rdx,%rdi
  xor    %eax,%eax
  call   <printf@plt>
  xor    %edi,%edi
  call   <exit@plt>
  lea    D23(%rip),%rdx
  jmp    L179
  nopl   0x0(%rax,%rax,1)
L15:
  sub    $0x47,%esi
  mov    %sil,(%r15)
  jmp    L179
  nopl   0x0(%rax,%rax,1)
L95:
  cmp    $0x4,%r13d
  jle    L130
  lea    -0x5(%r13),%r8d
  mov    %rbp,%rax
  mov    %r12,%rcx
  shr    $0x2,%r8d
  mov    %r8d,%r9d
  lea    0x4(%rbp,%r9,4),%rdi
L89:
  movzbl 0x1(%rax),%esi
  movzbl (%rax),%edx
  add    $0x3,%rcx
  add    $0x4,%rax
  sar    $0x4,%sil
  lea    (%rsi,%rdx,4),%edx
  mov    %dl,-0x3(%rcx)
  movzbl -0x3(%rax),%edx
  movzbl -0x2(%rax),%esi
  shl    $0x4,%edx
  sar    $0x2,%sil
  add    %esi,%edx
  mov    %dl,-0x2(%rcx)
  movzbl -0x2(%rax),%edx
  shl    $0x6,%edx
  add    -0x1(%rax),%dl
  mov    %dl,-0x1(%rcx)
  cmp    %rax,%rdi
  jne    L89
  lea    0x3(%r9,%r9,2),%rax
  add    %rax,%r12
  lea    0x4(,%r8,4),%eax
  cltq
  lea    0x3(%rax),%rsi
  lea    0x2(%rax),%rdx
  lea    0x1(%rax),%rcx
L101:
  add    %rbp,%rsi
  add    %rbp,%rcx
  add    %rbp,%rdx
  cmpb   $0xff,(%rsi)
  movzbl (%rcx),%edi
  je     L124
  movzbl 0x0(%rbp,%rax,1),%eax
  sar    $0x4,%dil
  lea    (%rdi,%rax,4),%eax
  lea    0x3(%r12),%rdi
  mov    %al,(%r12)
  movzbl (%rcx),%eax
  movzbl (%rdx),%ecx
  shl    $0x4,%eax
  sar    $0x2,%cl
  add    %ecx,%eax
  mov    %al,0x1(%r12)
  movzbl (%rdx),%eax
  shl    $0x6,%eax
  add    (%rsi),%al
  mov    %al,0x2(%r12)
L221:
  lea    0x0(%r13,%r13,2),%edx
  movb   $0x0,(%rdi)
  mov    %rbp,%rdi
  add    %edx,%edx
  lea    0x7(%rdx),%eax
  cmovns %edx,%eax
  sar    $0x3,%eax
  mov    %eax,(%rbx)
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    10b0 <free@plt>
  nopw   0x0(%rax,%rax,1)
L35:
  movb   $0xff,(%r15)
  jmp    L179
  nopl   0x0(%rax)
L148:
  movb   $0x3e,(%r15)
  jmp    L179
  nopl   0x0(%rax)
L38:
  add    $0x4,%esi
  mov    %sil,(%r15)
  jmp    L179
  nopl   0x0(%rax,%rax,1)
L124:
  cmpb   $0xff,(%rdx)
  je     L53
  movzbl 0x0(%rbp,%rax,1),%eax
  sar    $0x4,%dil
  lea    (%rdi,%rax,4),%eax
  lea    0x3(%r12),%rdi
  mov    %al,(%r12)
  movzbl (%rcx),%eax
  movzbl (%rdx),%ecx
  shl    $0x4,%eax
  sar    $0x2,%cl
  add    %ecx,%eax
  mov    %al,0x1(%r12)
  movsbl (%rdx),%eax
  shl    $0x6,%eax
  mov    %al,0x2(%r12)
  jmp    L221
  nopl   (%rax)
L53:
  cmp    $0xff,%dil
  je     L12
  movzbl 0x0(%rbp,%rax,1),%eax
  sar    $0x4,%dil
  lea    (%rdi,%rax,4),%eax
  lea    0x2(%r12),%rdi
  mov    %al,(%r12)
  movsbl (%rcx),%eax
  shl    $0x4,%eax
  mov    %al,0x1(%r12)
  jmp    L221
  nopl   0x0(%rax,%rax,1)
L130:
  mov    $0x1,%ecx
  mov    $0x2,%edx
  mov    $0x3,%esi
  xor    %eax,%eax
  jmp    L101
L12:
  lea    D7(%rip),%rdi
  call   <puts@plt>
  xor    %edi,%edi
  call   <exit@plt>
  mov    %r12,%rdi
  jmp    L221
```

tool_calls: name: disassemble_data
arguments: label: D23
type_guessed: string
name: disassemble_data
arguments: label: D7
type_guessed: string

tool: D23: 
%c:Not a valid base64 string


tool: D7: Not a valid base64 string

assistant: ```c
void base64_decode(char *src, char *dst, int *decode_len) {
  char *q = malloc(strlen(src) + 1);
  char *p = dst;
  char *temp = q;
  char *s = src;
  int len = strlen(src), i;
  memset(q, 0, strlen(src) + 1);
  while (*s) {
    if (*s >= 'A' && *s <= 'Z')
      *temp = *s - 'A';
    else if (*s >= 'a' && *s <= 'z')
      *temp = *s - 'a' + 26;
    else if (*s >= '0' && *s <= '9')
      *temp = *s - '0' + 52;
    else if (*s == '+')
      *temp = 62;
    else if (*s == '/')
      *temp = 63;
    else if (*s == '=')
      *temp = -1;
    else {
      printf("\n%c:Not a valid base64 string\n", *s);
      exit(0);
    }
    ++s;
    ++temp;
  }
  for (i = 0; i < len - 4; i += 4) {
    *p++ = (*(q + i) << 2) + (*(q + i + 1) >> 4);
    *p++ = (*(q + i + 1) << 4) + (*(q + i + 2) >> 2);
    *p++ = (*(q + i + 2) << 6) + (*(q + i + 3));
  }
  if (*(q + i + 3) != -1) {
    *p++ = (*(q + i) << 2) + (*(q + i + 1) >> 4);
    *p++ = (*(q + i + 1) << 4) + (*(q + i + 2) >> 2);
    *p++ = (*(q + i + 2) << 6) + *(q + i + 3);
  } else if (*(q + i + 2) != -1) {
    *p++ = (*(q + i) << 2) + (*(q + i + 1) >> 4);
    *p++ = (*(q + i + 1) << 4) + (*(q + i + 2) >> 2);
    *p++ = (*(q + i + 2) << 6);
  } else if (*(q + i + 1) != -1) {
    *p++ = (*(q + i) << 2) + (*(q + i + 1) >> 4);
    *p++ = (*(q + i + 1) << 4);
  } else {
    printf("Not a valid base64 string\n");
    exit(0);
  }
  *p = 0;
  *decode_len = len * 6 / 8;
  free(q);
}
```