user: What is the c source code of the assembly code below:

```asm
<qbase64_encode>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x90,%rsp
  mov    %rdi,-0x88(%rbp)
  mov    %rsi,-0x90(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movabs $0x4847464544434241,%rax
  movabs $0x504f4e4d4c4b4a49,%rdx
  mov    %rax,-0x50(%rbp)
  mov    %rdx,-0x48(%rbp)
  movabs $0x5857565554535251,%rax
  movabs $0x6665646362615a59,%rdx
  mov    %rax,-0x40(%rbp)
  mov    %rdx,-0x38(%rbp)
  movabs $0x6e6d6c6b6a696867,%rax
  movabs $0x767574737271706f,%rdx
  mov    %rax,-0x30(%rbp)
  mov    %rdx,-0x28(%rbp)
  movabs $0x333231307a797877,%rax
  movabs $0x2f2b393837363534,%rdx
  mov    %rax,-0x20(%rbp)
  mov    %rdx,-0x18(%rbp)
  cmpq   $0x0,-0x90(%rbp)
  jne    L40
  lea    D0(%rip),%rax
  mov    %rax,%rdi
  call   <strdup@plt>
  jmp    L30
L40:
  mov    -0x90(%rbp),%rax
  movabs $0xaaaaaaaaaaaaaaab,%rdx
  mul    %rdx
  mov    %rdx,%rsi
  shr    %rsi
  mov    -0x90(%rbp),%rcx
  movabs $0xaaaaaaaaaaaaaaab,%rdx
  mov    %rcx,%rax
  mul    %rdx
  mov    %rdx,%rax
  shr    %rax
  mov    %rax,%rdx
  add    %rdx,%rdx
  add    %rax,%rdx
  mov    %rcx,%rax
  sub    %rdx,%rax
  test   %rax,%rax
  setne  %al
  movzbl %al,%eax
  cltq
  add    %rsi,%rax
  shl    $0x2,%eax
  add    $0x1,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,-0x68(%rbp)
  cmpq   $0x0,-0x68(%rbp)
  jne    L130
  mov    $0x0,%eax
  jmp    L30
L130:
  mov    -0x68(%rbp),%rax
  mov    %rax,-0x78(%rbp)
  mov    -0x90(%rbp),%rax
  lea    -0x1(%rax),%rdx
  mov    -0x88(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x60(%rbp)
  movw   $0x0,-0x53(%rbp)
  movb   $0x0,-0x51(%rbp)
  mov    -0x88(%rbp),%rax
  mov    %rax,-0x70(%rbp)
  movl   $0x0,-0x80(%rbp)
  jmp    L10
L85:
  mov    -0x80(%rbp),%eax
  movslq %eax,%rdx
  imul   $0x55555556,%rdx,%rdx
  shr    $0x20,%rdx
  mov    %eax,%esi
  sar    $0x1f,%esi
  mov    %edx,%ecx
  sub    %esi,%ecx
  mov    %ecx,%edx
  add    %edx,%edx
  add    %ecx,%edx
  sub    %edx,%eax
  mov    %eax,-0x7c(%rbp)
  mov    -0x70(%rbp),%rax
  movzbl (%rax),%edx
  mov    -0x7c(%rbp),%eax
  cltq
  mov    %dl,-0x53(%rbp,%rax,1)
  cmpl   $0x1,-0x7c(%rbp)
  jg     L9
  mov    -0x70(%rbp),%rax
  cmp    -0x60(%rbp),%rax
  jb     L99
L9:
  movzbl -0x53(%rbp),%eax
  shr    $0x2,%al
  movzbl %al,%ecx
  mov    -0x78(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  movslq %ecx,%rdx
  movzbl -0x50(%rbp,%rdx,1),%edx
  mov    %dl,(%rax)
  movzbl -0x53(%rbp),%eax
  movzbl %al,%eax
  shl    $0x4,%eax
  and    $0x30,%eax
  mov    %eax,%edx
  movzbl -0x52(%rbp),%eax
  shr    $0x4,%al
  movzbl %al,%eax
  mov    %edx,%ecx
  or     %eax,%ecx
  mov    -0x78(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  movslq %ecx,%rdx
  movzbl -0x50(%rbp,%rdx,1),%edx
  mov    %dl,(%rax)
  cmpl   $0x0,-0x7c(%rbp)
  jle    L139
  movzbl -0x52(%rbp),%eax
  movzbl %al,%eax
  shl    $0x2,%eax
  and    $0x3c,%eax
  mov    %eax,%edx
  movzbl -0x51(%rbp),%eax
  shr    $0x6,%al
  movzbl %al,%eax
  or     %edx,%eax
  cltq
  movzbl -0x50(%rbp,%rax,1),%edx
  jmp    L21
L139:
  mov    $0x3d,%edx
L21:
  mov    -0x78(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x78(%rbp)
  mov    %dl,(%rax)
  cmpl   $0x1,-0x7c(%rbp)
  jle    L50
  movzbl -0x51(%rbp),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  cltq
  movzbl -0x50(%rbp,%rax,1),%edx
  jmp    L14
L50:
  mov    $0x3d,%edx
L14:
  mov    -0x78(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x78(%rbp)
  mov    %dl,(%rax)
  lea    -0x53(%rbp),%rax
  mov    $0x3,%edx
  mov    $0x0,%esi
  mov    %rax,%rdi
  call   <memset@plt>
  jmp    L74
L99:
  nop
L74:
  addq   $0x1,-0x70(%rbp)
  addl   $0x1,-0x80(%rbp)
L10:
  mov    -0x70(%rbp),%rax
  cmp    -0x60(%rbp),%rax
  jbe    L85
  mov    -0x78(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x68(%rbp),%rax
L30:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L98
  call   <__stack_chk_fail@plt>
L98:
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: data_label: D0
type: string

tool: 

assistant: ```c
char *qbase64_encode(const void *bin, size_t size) {
  const char B64CHARTBL[64] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
  if (size == 0) {
    return strdup("");
  }
  char *pszB64 = (char *)malloc(4 * ((size / 3) + ((size % 3 == 0) ? 0 : 1)) + 1);
  if (pszB64 == NULL) {
    return NULL;
  }
  char *pszB64Pt = pszB64;
  unsigned char *pBinPt, *pBinEnd = (unsigned char *)(bin + size - 1);
  unsigned char szIn[3] = {0, 0, 0};
  int nOffset;
  for (pBinPt = (unsigned char *)bin, nOffset = 0; pBinPt <= pBinEnd; pBinPt++, nOffset++) {
    int nIdxOfThree = nOffset % 3;
    szIn[nIdxOfThree] = *pBinPt;
    if (nIdxOfThree < 2 && pBinPt < pBinEnd)
      continue;
    *pszB64Pt++ = B64CHARTBL[((szIn[0] & 0xFC) >> 2)];
    *pszB64Pt++ = B64CHARTBL[(((szIn[0] & 0x03) << 4) | ((szIn[1] & 0xF0) >> 4))];
    *pszB64Pt++ = (nIdxOfThree >= 1) ? B64CHARTBL[(((szIn[1] & 0x0F) << 2) | ((szIn[2] & 0xC0) >> 6))] : '=';
    *pszB64Pt++ = (nIdxOfThree >= 2) ? B64CHARTBL[(szIn[2] & 0x3F)] : '=';
    memset((void *)szIn, 0, sizeof(szIn));
  }
  *pszB64Pt = '\0';
  return pszB64;
}
```