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

```asm
<lcg_rand>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  add    $0xffffffffffffff80,%rsp
  mov    %edi,-0x64(%rbp)
  movsd  %xmm0,-0x70(%rbp)
  mov    %rsi,-0x78(%rbp)
  mov    %edx,-0x68(%rbp)
  movsd  D34(%rip),%xmm0
  movsd  %xmm0,-0x48(%rbp)
  movsd  D8(%rip),%xmm0
  movsd  %xmm0,-0x40(%rbp)
  movsd  D4(%rip),%xmm0
  movsd  %xmm0,-0x38(%rbp)
  movsd  D6(%rip),%xmm0
  movsd  %xmm0,-0x30(%rbp)
  movsd  -0x70(%rbp),%xmm0
  movsd  %xmm0,-0x50(%rbp)
  mov    -0x64(%rbp),%eax
  cmp    -0x68(%rbp),%eax
  jle    L13
  mov    -0x68(%rbp),%eax
  mov    %eax,-0x64(%rbp)
L13:
  movl   $0x1,-0x54(%rbp)
  jmp    L10
L25:
  mov    -0x50(%rbp),%rax
  movq   %rax,%xmm0
  call   <floor@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x50(%rbp)
  movsd  -0x50(%rbp),%xmm0
  mulsd  -0x38(%rbp),%xmm0
  movsd  %xmm0,-0x28(%rbp)
  movsd  -0x50(%rbp),%xmm0
  mulsd  -0x30(%rbp),%xmm0
  movsd  %xmm0,-0x20(%rbp)
  movsd  -0x28(%rbp),%xmm0
  divsd  -0x48(%rbp),%xmm0
  movq   %xmm0,%rax
  movq   %rax,%xmm0
  call   <floor@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x18(%rbp)
  movsd  -0x20(%rbp),%xmm0
  divsd  -0x48(%rbp),%xmm0
  movq   %xmm0,%rax
  movq   %rax,%xmm0
  call   <floor@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x10(%rbp)
  movsd  -0x18(%rbp),%xmm0
  movapd %xmm0,%xmm1
  mulsd  -0x48(%rbp),%xmm1
  movsd  -0x28(%rbp),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x28(%rbp)
  movsd  -0x10(%rbp),%xmm0
  movapd %xmm0,%xmm1
  mulsd  -0x48(%rbp),%xmm1
  movsd  -0x20(%rbp),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x20(%rbp)
  movsd  -0x28(%rbp),%xmm0
  addsd  -0x20(%rbp),%xmm0
  addsd  -0x18(%rbp),%xmm0
  movsd  -0x10(%rbp),%xmm1
  addsd  %xmm1,%xmm0
  movsd  %xmm0,-0x50(%rbp)
  movsd  -0x50(%rbp),%xmm0
  divsd  -0x40(%rbp),%xmm0
  movq   %xmm0,%rax
  movq   %rax,%xmm0
  call   <floor@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x8(%rbp)
  movsd  -0x8(%rbp),%xmm0
  movapd %xmm0,%xmm1
  mulsd  -0x40(%rbp),%xmm1
  movsd  -0x50(%rbp),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x50(%rbp)
  mov    -0x54(%rbp),%eax
  cltq
  shl    $0x3,%rax
  lea    -0x8(%rax),%rdx
  mov    -0x78(%rbp),%rax
  add    %rdx,%rax
  movsd  -0x50(%rbp),%xmm0
  divsd  -0x40(%rbp),%xmm0
  movsd  %xmm0,(%rax)
  movsd  -0x50(%rbp),%xmm0
  movsd  %xmm0,-0x70(%rbp)
  addl   $0x1,-0x54(%rbp)
L10:
  mov    -0x54(%rbp),%eax
  cmp    -0x64(%rbp),%eax
  jle    L25
  movsd  -0x70(%rbp),%xmm0
  movq   %xmm0,%rax
  movq   %rax,%xmm0
  leave
  ret
```

tool_calls: name: unpack_data
arguments: data_tag: D34
datatype: f64
name: unpack_data
arguments: data_tag: D8
datatype: f64
name: unpack_data
arguments: data_tag: D4
datatype: f64
name: unpack_data
arguments: data_tag: D6
datatype: f64

tool: D34: 2147483648

tool: D8: 2147483647

tool: D4: 41160

tool: D6: 950665216

assistant: ```c
double lcg_rand(int N, double SEED, double *DUNIF, int NDIM) {
  int i;
  double DZ, DOVER, DZ1, DZ2, DOVER1, DOVER2;
  double DTWO31, DMDLS, DA1, DA2;
  DTWO31 = 2147483648.0;
  DMDLS = 2147483647.0;
  DA1 = 41160.0;
  DA2 = 950665216.0;
  DZ = SEED;
  if (N > NDIM)
    N = NDIM;
  for (i = 1; i <= N; i++) {
    DZ = floor(DZ);
    DZ1 = DZ * DA1;
    DZ2 = DZ * DA2;
    DOVER1 = floor(DZ1 / DTWO31);
    DOVER2 = floor(DZ2 / DTWO31);
    DZ1 = DZ1 - DOVER1 * DTWO31;
    DZ2 = DZ2 - DOVER2 * DTWO31;
    DZ = DZ1 + DZ2 + DOVER1 + DOVER2;
    DOVER = floor(DZ / DMDLS);
    DZ = DZ - DOVER * DMDLS;
    DUNIF[i - 1] = DZ / DMDLS;
    SEED = DZ;
  }
  return SEED;
}
```