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

```asm
<RIPEMD160_Final>:
  endbr64
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  mov    %rdi,%rbx
  mov    %rsi,%rbp
  mov    0x38(%rsi),%r12
  mov    (%rsi),%rdi
  movb   $0x80,(%r12,%rdi,1)
  add    $0x1,%rdi
  mov    D8(%rip),%rax
  mov    (%rax),%edx
  lea    -0x8(%rdx),%eax
  cltq
  cmp    %rdi,%rax
  jb     L11
L12:
  mov    D8(%rip),%r13
  mov    0x0(%r13),%eax
  lea    -0x8(%rax),%edx
  sub    %edi,%edx
  add    %r12,%rdi
  mov    $0x0,%esi
  call   <memset@plt>
  movslq 0x0(%r13),%rax
  lea    -0x8(%r12,%rax,1),%rax
  mov    0x8(%rbp),%edx
  mov    %dl,(%rax)
  mov    0x8(%rbp),%edx
  movzbl %dh,%ecx
  mov    %cl,0x1(%rax)
  movswl 0xa(%rbp),%edx
  mov    %dl,0x2(%rax)
  movsbl 0xb(%rbp),%edx
  mov    %dl,0x3(%rax)
  mov    0xc(%rbp),%edx
  mov    %dl,0x4(%rax)
  mov    0xc(%rbp),%edx
  movzbl %dh,%ecx
  mov    %cl,0x5(%rax)
  movswl 0xe(%rbp),%edx
  mov    %dl,0x6(%rax)
  lea    0x8(%rax),%r12
  movsbl 0xf(%rbp),%edx
  mov    %dl,0x7(%rax)
  movslq 0x0(%r13),%rax
  sub    %rax,%r12
  mov    $0x1,%edx
  mov    %r12,%rsi
  mov    %rbp,%rdi
  call   <ripemd160_block_data_order@plt>
  movq   $0x0,0x0(%rbp)
  mov    0x0(%r13),%esi
  mov    %r12,%rdi
  call   <OPENSSL_cleanse@plt>
  mov    0x10(%rbp),%rax
  mov    %al,(%rbx)
  movzbl %ah,%ecx
  mov    %cl,0x1(%rbx)
  mov    %rax,%rdx
  shr    $0x10,%rdx
  mov    %dl,0x2(%rbx)
  shr    $0x18,%rax
  mov    %al,0x3(%rbx)
  mov    0x18(%rbp),%rax
  mov    %al,0x4(%rbx)
  movzbl %ah,%ecx
  mov    %cl,0x5(%rbx)
  mov    %rax,%rdx
  shr    $0x10,%rdx
  mov    %dl,0x6(%rbx)
  shr    $0x18,%rax
  mov    %al,0x7(%rbx)
  mov    0x20(%rbp),%rax
  mov    %al,0x8(%rbx)
  movzbl %ah,%ecx
  mov    %cl,0x9(%rbx)
  mov    %rax,%rdx
  shr    $0x10,%rdx
  mov    %dl,0xa(%rbx)
  shr    $0x18,%rax
  mov    %al,0xb(%rbx)
  mov    0x28(%rbp),%rax
  mov    %al,0xc(%rbx)
  movzbl %ah,%ecx
  mov    %cl,0xd(%rbx)
  mov    %rax,%rdx
  shr    $0x10,%rdx
  mov    %dl,0xe(%rbx)
  shr    $0x18,%rax
  mov    %al,0xf(%rbx)
  mov    0x30(%rbp),%rax
  mov    %al,0x10(%rbx)
  movzbl %ah,%ecx
  mov    %cl,0x11(%rbx)
  mov    %rax,%rdx
  shr    $0x10,%rdx
  mov    %dl,0x12(%rbx)
  shr    $0x18,%rax
  mov    %al,0x13(%rbx)
  mov    $0x1,%eax
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
L11:
  sub    %edi,%edx
  add    %r12,%rdi
  mov    $0x0,%esi
  call   <memset@plt>
  mov    $0x1,%edx
  mov    %r12,%rsi
  mov    %rbp,%rdi
  call   <ripemd160_block_data_order@plt>
  mov    $0x0,%edi
  jmp    L12
```

assistant: ```c
int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c) {
  unsigned char *p = (unsigned char *)c->data;
  size_t n = c->num;
  p[n] = 0x80;
  n++;
  if (n > (RIPEMD160_CBLOCK - 8)) {
    memset(p + n, 0, RIPEMD160_CBLOCK - n);
    n = 0;
    ripemd160_block_data_order(c, p, 1);
  }
  memset(p + n, 0, RIPEMD160_CBLOCK - 8 - n);
  p += RIPEMD160_CBLOCK - 8;
  (void)(*((p)++) = (unsigned char)(((c->Nl)) & 0xff), *((p)++) = (unsigned char)(((c->Nl) >> 8) & 0xff), *((p)++) = (unsigned char)(((c->Nl) >> 16) & 0xff), *((p)++) = (unsigned char)(((c->Nl) >> 24) & 0xff), c->Nl);
  (void)(*((p)++) = (unsigned char)(((c->Nh)) & 0xff), *((p)++) = (unsigned char)(((c->Nh) >> 8) & 0xff), *((p)++) = (unsigned char)(((c->Nh) >> 16) & 0xff), *((p)++) = (unsigned char)(((c->Nh) >> 24) & 0xff), c->Nh);
  p -= RIPEMD160_CBLOCK;
  ripemd160_block_data_order(c, p, 1);
  c->num = 0;
  OPENSSL_cleanse(p, RIPEMD160_CBLOCK);
  do {
    unsigned long ll;
    ll = (c)->A;
    (void)(*(((md))++) = (unsigned char)(((ll)) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 8) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 16) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 24) & 0xff), ll);
    ll = (c)->B;
    (void)(*(((md))++) = (unsigned char)(((ll)) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 8) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 16) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 24) & 0xff), ll);
    ll = (c)->C;
    (void)(*(((md))++) = (unsigned char)(((ll)) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 8) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 16) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 24) & 0xff), ll);
    ll = (c)->D;
    (void)(*(((md))++) = (unsigned char)(((ll)) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 8) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 16) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 24) & 0xff), ll);
    ll = (c)->E;
    (void)(*(((md))++) = (unsigned char)(((ll)) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 8) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 16) & 0xff), *(((md))++) = (unsigned char)(((ll) >> 24) & 0xff), ll);
  } while (0);
  return 1;
}
```