user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<qbase64_encode>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x68,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x58(%rsp)
  xor    %eax,%eax
  movabs $0x4847464544434241,%rax
  movabs $0x504f4e4d4c4b4a49,%rdx
  mov    %rax,0x10(%rsp)
  mov    %rdx,0x18(%rsp)
  movabs $0x5857565554535251,%rax
  movabs $0x6665646362615a59,%rdx
  mov    %rax,0x20(%rsp)
  mov    %rdx,0x28(%rsp)
  movabs $0x6e6d6c6b6a696867,%rax
  movabs $0x767574737271706f,%rdx
  mov    %rax,0x30(%rsp)
  mov    %rdx,0x38(%rsp)
  movabs $0x333231307a797877,%rax
  movabs $0x2f2b393837363534,%rdx
  mov    %rax,0x40(%rsp)
  mov    %rdx,0x48(%rsp)
  test   %rsi,%rsi
  je     L125
  mov    %rdi,%rbx
  mov    %rsi,%rbp
  movabs $0xaaaaaaaaaaaaaaab,%rdx
  mov    %rsi,%rax
  mul    %rdx
  mov    %rdx,%rcx
  shr    %rcx
  and    $0xfffffffffffffffe,%rdx
  add    %rcx,%rdx
  cmp    %rdx,%rsi
  setne  %al
  movzbl %al,%eax
  add    %rcx,%rax
  lea    0x1(,%rax,4),%edi
  call   <malloc@plt>
  mov    %rax,%r14
  test   %rax,%rax
  je     L104
  lea    -0x1(%rbx,%rbp,1),%r12
  movw   $0x0,0xd(%rsp)
  movb   $0x0,0xf(%rsp)
  cmp    %r12,%rbx
  ja     L68
  mov    %rax,%rcx
  mov    $0x0,%ebp
  mov    $0x3d,%r13d
  jmp    L50
L125:
  lea    D9(%rip),%rdi
  call   <strdup@plt>
  mov    %rax,%r14
  jmp    L31
L62:
  movzbl 0xd(%rsp),%edx
  shr    $0x2,%dl
  and    $0x3f,%edx
  movzbl 0x10(%rsp,%rdx,1),%edx
  mov    %dl,(%rcx)
  movzbl 0xd(%rsp),%edx
  shl    $0x4,%edx
  and    $0x30,%edx
  movzbl 0xe(%rsp),%esi
  shr    $0x4,%sil
  movzbl %sil,%esi
  or     %esi,%edx
  movslq %edx,%rdx
  movzbl 0x10(%rsp,%rdx,1),%edx
  mov    %dl,0x1(%rcx)
  mov    %r13d,%edx
  test   %eax,%eax
  jle    L114
  movzbl 0xe(%rsp),%edx
  shl    $0x2,%edx
  and    $0x3c,%edx
  movzbl 0xf(%rsp),%esi
  shr    $0x6,%sil
  movzbl %sil,%esi
  or     %esi,%edx
  movslq %edx,%rdx
  movzbl 0x10(%rsp,%rdx,1),%edx
L114:
  mov    %dl,0x2(%rcx)
  mov    %r13d,%edx
  cmp    $0x1,%eax
  jle    L34
  movzbl 0xf(%rsp),%eax
  and    $0x3f,%eax
  movzbl 0x10(%rsp,%rax,1),%edx
L34:
  lea    0x4(%rcx),%r15
  mov    %dl,0x3(%rcx)
  lea    0xd(%rsp),%rdi
  mov    $0x3,%edx
  mov    $0x0,%esi
  call   <memset@plt>
  mov    %r15,%rcx
L11:
  add    $0x1,%rbx
  add    $0x1,%ebp
  cmp    %rbx,%r12
  jb     L42
L50:
  movslq %ebp,%rax
  imul   $0x55555556,%rax,%rax
  shr    $0x20,%rax
  mov    %ebp,%edx
  sar    $0x1f,%edx
  sub    %edx,%eax
  lea    (%rax,%rax,2),%edx
  mov    %ebp,%eax
  sub    %edx,%eax
  movslq %eax,%rdx
  movzbl (%rbx),%esi
  mov    %sil,0xd(%rsp,%rdx,1)
  cmp    $0x1,%eax
  jg     L62
  cmp    %rbx,%r12
  jbe    L62
  jmp    L11
L68:
  mov    %rax,%rcx
L42:
  movb   $0x0,(%rcx)
L31:
  mov    0x58(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L84
  mov    %r14,%rax
  add    $0x68,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L104:
  mov    $0x0,%r14d
  jmp    L31
L84:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: extract_symbolic_data
arguments: label: D9
datatype: 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;
}
```