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

```asm
<base64_encode>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x28(%rbp)
  mov    %esi,-0x2c(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  movl   $0x0,-0x14(%rbp)
  jmp    L31
L13:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  shr    $0x2,%al
  movzbl %al,%ecx
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movslq %ecx,%rdx
  lea    D38(%rip),%rcx
  movzbl (%rdx,%rcx,1),%edx
  mov    %dl,(%rax)
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x4,%eax
  and    $0x30,%eax
  mov    %eax,%edx
  mov    -0x10(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  shr    $0x4,%al
  movzbl %al,%eax
  lea    (%rdx,%rax,1),%ecx
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movslq %ecx,%rdx
  lea    D38(%rip),%rcx
  movzbl (%rdx,%rcx,1),%edx
  mov    %dl,(%rax)
  mov    -0x10(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x2,%eax
  and    $0x3c,%eax
  mov    %eax,%edx
  mov    -0x10(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  shr    $0x6,%al
  movzbl %al,%eax
  lea    (%rdx,%rax,1),%ecx
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movslq %ecx,%rdx
  lea    D38(%rip),%rcx
  movzbl (%rdx,%rcx,1),%edx
  mov    %dl,(%rax)
  mov    -0x10(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  mov    %eax,%ecx
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movslq %ecx,%rdx
  lea    D38(%rip),%rcx
  movzbl (%rdx,%rcx,1),%edx
  mov    %dl,(%rax)
  addq   $0x3,-0x10(%rbp)
  addl   $0x3,-0x14(%rbp)
L31:
  mov    -0x14(%rbp),%eax
  cmp    -0x2c(%rbp),%eax
  jl     L13
  mov    -0x2c(%rbp),%eax
  add    $0x1,%eax
  cmp    %eax,-0x14(%rbp)
  jne    L5
  mov    -0x8(%rbp),%rax
  sub    $0x1,%rax
  movb   $0x3d,(%rax)
  jmp    L16
L5:
  mov    -0x2c(%rbp),%eax
  add    $0x2,%eax
  cmp    %eax,-0x14(%rbp)
  jne    L16
  mov    -0x8(%rbp),%rax
  sub    $0x2,%rax
  movb   $0x3d,(%rax)
  mov    -0x8(%rbp),%rdx
  sub    $0x1,%rdx
  movzbl (%rax),%eax
  mov    %al,(%rdx)
L16:
  mov    -0x8(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x8(%rbp),%rax
  sub    -0x38(%rbp),%rax
  pop    %rbp
  ret
```

assistant: ```c
int base64_encode(const char *str, int length, char *b64store) {
  static char tbl[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', '+', '/'};
  int i;
  const unsigned char *s = (const unsigned char *)str;
  char *p = b64store;
  for (i = 0; i < length; i += 3) {
    *p++ = tbl[s[0] >> 2];
    *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
    *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
    *p++ = tbl[s[2] & 0x3f];
    s += 3;
  }
  if (i == length + 1)
    *(p - 1) = '=';
  else if (i == length + 2)
    *(p - 1) = *(p - 2) = '=';
  *p = '\0';
  return p - b64store;
}
```