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

```asm
<MatrixInv>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  mov    %rsi,%r12
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  mov    $0x18,%edi
  sub    $0x8,%rsp
  call   <malloc@plt>
  mov    $0x18,%edi
  mov    %rax,%rbp
  call   <malloc@plt>
  mov    $0x18,%edi
  mov    %rax,%r14
  mov    %rax,0x0(%rbp)
  call   <malloc@plt>
  mov    $0x18,%edi
  mov    %rax,%r13
  mov    %rax,0x8(%rbp)
  call   <malloc@plt>
  movsd  0x10(%rbx),%xmm0
  movupd (%rbx),%xmm1
  mov    $0x3,%esi
  movupd 0x18(%rbx),%xmm2
  movupd 0x30(%rbx),%xmm3
  mov    %rax,0x10(%rbp)
  mov    %rbp,%rdi
  movsd  %xmm0,0x10(%r14)
  movsd  0x28(%rbx),%xmm0
  movups %xmm1,(%r14)
  movsd  %xmm0,0x10(%r13)
  movsd  0x40(%rbx),%xmm0
  movups %xmm2,0x0(%r13)
  movups %xmm3,(%rax)
  movsd  %xmm0,0x10(%rax)
  xor    %eax,%eax
  call   <Determinant@plt>
  test   %eax,%eax
  jne    L22
  lea    D0(%rip),%rdi
  call   <puts@plt>
L0:
  mov    0x0(%rbp),%rdi
  call   <free@plt>
  mov    0x8(%rbp),%rdi
  call   <free@plt>
  mov    0x10(%rbp),%rdi
  call   <free@plt>
  add    $0x8,%rsp
  mov    %rbp,%rdi
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1090 <free@plt>
  nop
L22:
  mov    $0x18,%edi
  mov    %eax,%r15d
  xor    %ebx,%ebx
  call   <malloc@plt>
  mov    $0x18,%edi
  mov    %rax,%r13
  call   <malloc@plt>
  mov    %rax,%r14
L6:
  mov    $0x18,%edi
  call   <malloc@plt>
  mov    $0x18,%edi
  mov    %rax,0x0(%r13,%rbx,1)
  call   <malloc@plt>
  mov    %rax,(%r14,%rbx,1)
  add    $0x8,%rbx
  cmp    $0x18,%rbx
  jne    L6
  pxor   %xmm0,%xmm0
  mov    $0x3,%edx
  mov    %r13,%rsi
  mov    %rbp,%rdi
  cvtsi2sd %r15d,%xmm0
  mov    $0x1,%eax
  xor    %ebx,%ebx
  call   <InverseMatrix@plt>
  mov    0x0(%r13),%rax
  movsd  (%rax),%xmm0
  movsd  %xmm0,(%r12)
  movsd  0x8(%rax),%xmm0
  movsd  %xmm0,0x8(%r12)
  movsd  0x10(%rax),%xmm0
  mov    0x8(%r13),%rax
  movsd  %xmm0,0x10(%r12)
  movsd  (%rax),%xmm0
  movsd  %xmm0,0x18(%r12)
  movsd  0x8(%rax),%xmm0
  movsd  %xmm0,0x20(%r12)
  movsd  0x10(%rax),%xmm0
  mov    0x10(%r13),%rax
  movsd  %xmm0,0x28(%r12)
  movsd  (%rax),%xmm0
  movsd  %xmm0,0x30(%r12)
  movsd  0x8(%rax),%xmm0
  movsd  %xmm0,0x38(%r12)
  movsd  0x10(%rax),%xmm0
  movsd  %xmm0,0x40(%r12)
L32:
  mov    (%r14,%rbx,1),%rdi
  call   <free@plt>
  mov    0x0(%r13,%rbx,1),%rdi
  add    $0x8,%rbx
  call   <free@plt>
  cmp    $0x18,%rbx
  jne    L32
  mov    %r14,%rdi
  call   <free@plt>
  mov    %r13,%rdi
  call   <free@plt>
  jmp    L0
```

tool_calls: name: disassemble_data
arguments: tag: D0
type_infered: string

tool: D0: 
No determinant(A)

assistant: ```c
void MatrixInv(double matrix_in[3][3], double matrix_out[3][3]) {
  int userN = 3;
  int userM = 2;
  int row = 0;
  int column = 0;
  double **matrixA;
  double **inversedMatrixA;
  double **multiplicationalMatrixA;
  double determinantResult = 0;
  matrixA = (double **)malloc(sizeof(double *) * userN);
  for (row = 0; row < userN; row++) {
    matrixA[row] = (double *)malloc(sizeof(double) * userN);
  }
  for (row = 0; row < userN; row++) {
    for (column = 0; column < userN; column++) {
      matrixA[row][column] = matrix_in[row][column];
    }
  }
  determinantResult = Determinant(matrixA, userN);
  if (!determinantResult) {
    printf("\nNo determinant(A)\n");
  } else {
    inversedMatrixA = (double **)malloc(sizeof(double *) * userN);
    multiplicationalMatrixA = (double **)malloc(sizeof(double *) * userN);
    for (row = 0; row < userN; row++) {
      inversedMatrixA[row] = (double *)malloc(sizeof(double) * userN);
      multiplicationalMatrixA[row] = (double *)malloc(sizeof(double) * userN);
    }
    InverseMatrix(matrixA, inversedMatrixA, userN, determinantResult);
    for (row = 0; row < userN; row++) {
      for (column = 0; column < userN; column++) {
        matrix_out[row][column] = inversedMatrixA[row][column];
      }
    }
    for (row = 0; row < userN; row++) {
      free(multiplicationalMatrixA[row]);
      free(inversedMatrixA[row]);
    }
    free(multiplicationalMatrixA);
    free(inversedMatrixA);
  }
  for (row = 0; row < userN; row++) {
    free(matrixA[row]);
  }
  free(matrixA);
}
```