user: Translate the below assembly code into C programming language:

```asm
<base64_encode>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %rcx,-0x30(%rbp)
  jmp    L183
L133:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <to_uchar@plt>
  sar    $0x2,%eax
  and    $0x3f,%eax
  mov    %eax,%ecx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movslq %ecx,%rdx
  lea    D3(%rip),%rcx
  movzbl (%rdx,%rcx,1),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x30(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  je     L20
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <to_uchar@plt>
  shl    $0x4,%eax
  mov    %eax,%ebx
  subq   $0x1,-0x20(%rbp)
  cmpq   $0x0,-0x20(%rbp)
  je     L86
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <to_uchar@plt>
  sar    $0x4,%eax
  jmp    L192
L86:
  mov    $0x0,%eax
L192:
  add    %ebx,%eax
  and    $0x3f,%eax
  mov    %eax,%ecx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movslq %ecx,%rdx
  lea    D3(%rip),%rcx
  movzbl (%rdx,%rcx,1),%edx
  mov    %dl,(%rax)
  subq   $0x1,-0x30(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  je     L114
  cmpq   $0x0,-0x20(%rbp)
  je     L176
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <to_uchar@plt>
  lea    0x0(,%rax,4),%ebx
  subq   $0x1,-0x20(%rbp)
  cmpq   $0x0,-0x20(%rbp)
  je     L61
  mov    -0x18(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <to_uchar@plt>
  sar    $0x6,%eax
  jmp    L83
L61:
  mov    $0x0,%eax
L83:
  add    %ebx,%eax
  and    $0x3f,%eax
  cltq
  lea    D3(%rip),%rdx
  movzbl (%rax,%rdx,1),%edx
  jmp    L39
L176:
  mov    $0x3d,%edx
L39:
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x28(%rbp)
  mov    %dl,(%rax)
  subq   $0x1,-0x30(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  je     L59
  cmpq   $0x0,-0x20(%rbp)
  je     L24
  mov    -0x18(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <to_uchar@plt>
  and    $0x3f,%eax
  cltq
  lea    D3(%rip),%rdx
  movzbl (%rax,%rdx,1),%edx
  jmp    L62
L24:
  mov    $0x3d,%edx
L62:
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x28(%rbp)
  mov    %dl,(%rax)
  subq   $0x1,-0x30(%rbp)
  cmpq   $0x0,-0x30(%rbp)
  je     L203
  cmpq   $0x0,-0x20(%rbp)
  je     L35
  subq   $0x1,-0x20(%rbp)
L35:
  cmpq   $0x0,-0x20(%rbp)
  je     L183
  addq   $0x3,-0x18(%rbp)
L183:
  cmpq   $0x0,-0x20(%rbp)
  je     L145
  cmpq   $0x0,-0x30(%rbp)
  jne    L133
  jmp    L145
L20:
  nop
  jmp    L145
L114:
  nop
  jmp    L145
L59:
  nop
  jmp    L145
L203:
  nop
L145:
  cmpq   $0x0,-0x30(%rbp)
  je     L211
  mov    -0x28(%rbp),%rax
  movb   $0x0,(%rax)
L211:
  nop
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
void base64_encode(const char *in, size_t inlen, char *out, size_t outlen) {
  static const char b64str[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  while (inlen && outlen) {
    *out++ = b64str[(to_uchar(in[0]) >> 2) & 0x3f];
    if (!--outlen)
      break;
    *out++ = b64str[((to_uchar(in[0]) << 4) + (--inlen ? to_uchar(in[1]) >> 4 : 0)) & 0x3f];
    if (!--outlen)
      break;
    *out++ = (inlen ? b64str[((to_uchar(in[1]) << 2) + (--inlen ? to_uchar(in[2]) >> 6 : 0)) & 0x3f] : '=');
    if (!--outlen)
      break;
    *out++ = inlen ? b64str[to_uchar(in[2]) & 0x3f] : '=';
    if (!--outlen)
      break;
    if (inlen)
      inlen--;
    if (inlen)
      in += 3;
  }
  if (outlen)
    *out = '\0';
}
```