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

```asm
<k128_decrypt>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x58,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %rcx,-0x50(%rbp)
  mov    %r8,-0x58(%rbp)
  movb   $0x32,-0x2a(%rbp)
  movzbl -0x2a(%rbp),%eax
  lea    -0x1(%rax),%edx
  mov    %dl,-0x2a(%rbp)
  movzbl %al,%eax
  lea    0x0(,%rax,8),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%rcx
  mov    -0x40(%rbp),%rax
  sub    %rcx,%rax
  mov    %rax,%rdx
  mov    -0x48(%rbp),%rax
  mov    %rdx,(%rax)
  movzbl -0x2a(%rbp),%eax
  lea    -0x1(%rax),%edx
  mov    %dl,-0x2a(%rbp)
  movzbl %al,%eax
  lea    0x0(,%rax,8),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <inv_ball@plt>
  mov    -0x50(%rbp),%rdx
  mov    %rax,(%rdx)
  movb   $0xc,-0x29(%rbp)
  jmp    L12
L13:
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x48(%rbp),%rax
  mov    (%rax),%rax
  xor    %rdx,%rax
  mov    %rax,-0x28(%rbp)
  movzbl -0x2a(%rbp),%eax
  lea    0x0(,%rax,8),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%rbx
  movzbl -0x2a(%rbp),%eax
  shl    $0x3,%rax
  lea    -0x8(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%rax
  mov    -0x28(%rbp),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <ball@plt>
  mov    -0x28(%rbp),%rdx
  add    %rdx,%rax
  mov    %rbx,%rsi
  mov    %rax,%rdi
  call   <ball@plt>
  mov    %rax,-0x20(%rbp)
  movzbl -0x2a(%rbp),%eax
  shl    $0x3,%rax
  lea    -0x8(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%rax
  mov    -0x28(%rbp),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <ball@plt>
  mov    -0x20(%rbp),%rdx
  add    %rdx,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  xor    -0x18(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x50(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x48(%rbp),%rax
  mov    (%rax),%rax
  xor    -0x18(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x48(%rbp),%rax
  mov    %rdx,(%rax)
  movzbl -0x2a(%rbp),%eax
  shl    $0x3,%rax
  lea    -0x18(%rax),%rdx
  mov    -0x58(%rbp),%rax
  add    %rdx,%rax
  mov    (%rax),%rdx
  mov    -0x48(%rbp),%rax
  mov    (%rax),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <inv_ball@plt>
  mov    -0x48(%rbp),%rdx
  mov    %rax,(%rdx)
  mov    -0x50(%rbp),%rax
  mov    (%rax),%rax
  movzbl -0x2a(%rbp),%edx
  shl    $0x3,%rdx
  lea    -0x10(%rdx),%rcx
  mov    -0x58(%rbp),%rdx
  add    %rcx,%rdx
  mov    (%rdx),%rcx
  sub    %rcx,%rax
  mov    %rax,%rdx
  mov    -0x50(%rbp),%rax
  mov    %rdx,(%rax)
  subb   $0x4,-0x2a(%rbp)
  movzbl -0x29(%rbp),%eax
  sub    $0x1,%eax
  mov    %al,-0x29(%rbp)
L12:
  cmpb   $0x0,-0x29(%rbp)
  jne    L13
  nop
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
void k128_decrypt(unsigned long long int Yl, unsigned long long int Yr, unsigned long long int *Xl, unsigned long long int *Xr, unsigned long long int *subkeys) {
  unsigned char k, i;
  unsigned long long int Y1, Y2, Z;
  k = 50;
  *Xl = Yr - subkeys[k--];
  *Xr = inv_ball(Yl, subkeys[k--]);
  for (i = 12; i >= 1; i--) {
    Y1 = *Xr ^ *Xl;
    Y2 = ball(ball(subkeys[k - 1], Y1) + Y1, subkeys[k]);
    Z = ball(subkeys[k - 1], Y1) + Y2;
    *Xr ^= Z;
    *Xl ^= Z;
    *Xl = inv_ball(*Xl, subkeys[k - 3]);
    *Xr = *Xr - subkeys[k - 2];
    k -= 4;
  }
  return;
}
```