user: Converte this assembly snippet into its equivalent C code:

```asm
<montgomery_ladder>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %edi,0x8(%rsp)
  mov    %esi,0xc(%rsp)
  mov    %edx,0x10(%rsp)
  mov    %ecx,0x14(%rsp)
  mov    %r8d,0x18(%rsp)
  mov    %r9d,0x1c(%rsp)
  mov    $0x0,%r13d
  mov    %r13d,%edi
  call   <mpz_init@plt>
  mov    $0x0,%r12d
  mov    %r12d,%edi
  call   <mpz_init@plt>
  mov    $0x0,%r14d
  mov    %r14d,%edi
  call   <mpz_init@plt>
  mov    $0x0,%eax
  mov    %eax,(%rsp)
  mov    %eax,%edi
  call   <mpz_init@plt>
  mov    $0x0,%r15d
  mov    %r15d,%edi
  call   <mpz_init@plt>
  mov    $0x0,%ebx
  mov    %ebx,0x4(%rsp)
  mov    %ebx,%edi
  call   <mpz_init@plt>
  mov    %ebx,%edi
  call   <mpz_init@plt>
  mov    $0x0,%ebp
  mov    %ebp,%edi
  call   <mpz_init@plt>
  mov    0x8(%rsp),%esi
  mov    %r13d,%edi
  call   <mpz_set@plt>
  mov    0xc(%rsp),%esi
  mov    %r12d,%edi
  call   <mpz_set@plt>
  mov    0x10(%rsp),%esi
  mov    %r14d,%edi
  call   <mpz_set@plt>
  mov    0x14(%rsp),%esi
  mov    (%rsp),%edi
  call   <mpz_set@plt>
  mov    %r12d,%edx
  mov    %r14d,%esi
  mov    %ebx,%edi
  call   <mpz_mul@plt>
  mov    %r13d,%edx
  mov    (%rsp),%esi
  mov    %ebp,%edi
  call   <mpz_mul@plt>
  mov    %ebx,%edx
  mov    %ebp,%esi
  mov    %r15d,%edi
  call   <mpz_add@plt>
  mov    %ebx,%edx
  mov    %ebp,%esi
  mov    0x4(%rsp),%edi
  call   <mpz_sub@plt>
  mov    0x4(%rsp),%edi
  mov    %edi,%edx
  mov    %edi,%esi
  call   <mpz_mul@plt>
  mov    (%rsp),%edx
  mov    %r12d,%esi
  mov    %ebp,%edi
  call   <mpz_mul@plt>
  mov    %ebp,%edx
  mov    0x1c(%rsp),%esi
  mov    %r12d,%edi
  call   <mpz_mul@plt>
  mov    %ebp,%edx
  mov    %ebp,%esi
  mov    %ebx,%edi
  call   <mpz_mul@plt>
  mov    %r14d,%edx
  mov    %r13d,%esi
  mov    %r13d,%edi
  call   <mpz_mul@plt>
  mov    %ebx,%edx
  mov    0x60(%rsp),%esi
  mov    %ebx,%edi
  call   <mpz_mul@plt>
  mov    %r12d,%edx
  mov    %r13d,%esi
  mov    %r13d,%edi
  call   <mpz_add@plt>
  mov    %ebx,%edx
  mov    %ebx,%esi
  mov    %ebx,%edi
  call   <mpz_add@plt>
  mov    %r15d,%edx
  mov    %r13d,%esi
  mov    %r13d,%edi
  call   <mpz_mul@plt>
  mov    0x4(%rsp),%edx
  mov    0x68(%rsp),%esi
  mov    %r12d,%edi
  call   <mpz_mul@plt>
  mov    %ebx,%edx
  mov    %r13d,%esi
  mov    %r15d,%edi
  call   <mpz_add@plt>
  mov    %r15d,%edx
  mov    %r15d,%esi
  mov    %r15d,%edi
  call   <mpz_add@plt>
  mov    %r14d,%edx
  mov    %r14d,%esi
  mov    %ebx,%edi
  call   <mpz_add@plt>
  mov    %r12d,%edx
  mov    %r15d,%esi
  mov    %r15d,%edi
  call   <mpz_sub@plt>
  mov    (%rsp),%eax
  mov    %eax,%edx
  mov    %eax,%esi
  mov    %ebp,%edi
  call   <mpz_add@plt>
  mov    %ebp,%edx
  mov    %ebx,%esi
  mov    %r13d,%edi
  call   <mpz_mul@plt>
  mov    (%rsp),%eax
  mov    %eax,%edx
  mov    %eax,%esi
  mov    %r12d,%edi
  call   <mpz_mul@plt>
  mov    %r14d,%edx
  mov    %r14d,%esi
  mov    %r14d,%edi
  call   <mpz_mul@plt>
  mov    %r12d,%edx
  mov    0x1c(%rsp),%esi
  mov    (%rsp),%edi
  call   <mpz_mul@plt>
  mov    (%rsp),%edx
  mov    %r14d,%esi
  mov    %ebx,%edi
  call   <mpz_sub@plt>
  mov    (%rsp),%edx
  mov    %r14d,%esi
  mov    %ebp,%edi
  call   <mpz_add@plt>
  mov    %r12d,%edx
  mov    %r12d,%esi
  mov    %r12d,%edi
  call   <mpz_add@plt>
  mov    %r12d,%edx
  mov    0x60(%rsp),%esi
  mov    %r14d,%edi
  call   <mpz_mul@plt>
  mov    %r13d,%edx
  mov    %ebp,%esi
  mov    %ebp,%edi
  call   <mpz_mul@plt>
  mov    %r12d,%edx
  mov    %r14d,%esi
  mov    %r12d,%edi
  call   <mpz_mul@plt>
  mov    %r14d,%edx
  mov    %r13d,%esi
  mov    %r13d,%edi
  call   <mpz_mul@plt>
  mov    %ebx,%edx
  mov    %ebx,%esi
  mov    %ebx,%edi
  call   <mpz_mul@plt>
  mov    %r13d,%edx
  mov    %ebx,%esi
  mov    %ebx,%edi
  call   <mpz_sub@plt>
  mov    %r12d,%edx
  mov    %ebp,%esi
  mov    %ebp,%edi
  call   <mpz_add@plt>
  mov    0x18(%rsp),%r14d
  mov    %r14d,%edx
  mov    %r15d,%esi
  mov    %r15d,%edi
  call   <mpz_mod@plt>
  mov    %r14d,%edx
  mov    0x4(%rsp),%edi
  mov    %edi,%esi
  call   <mpz_mod@plt>
  mov    %r14d,%edx
  mov    %ebx,%esi
  mov    %ebx,%edi
  call   <mpz_mod@plt>
  mov    %r14d,%edx
  mov    %ebp,%esi
  mov    %ebp,%edi
  call   <mpz_mod@plt>
  lea    D34(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    0x8(%rsp),%esi
  lea    D81(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    0xc(%rsp),%ebx
  mov    %ebx,%esi
  lea    D39(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    0x10(%rsp),%esi
  lea    D35(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    %ebx,%esi
  lea    D56(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  cmpl   $0x1,0x70(%rsp)
  je     L24
  cmpl   $0x2,0x70(%rsp)
  je     L12
L18:
  mov    0x18(%rsp),%r13d
  mov    %r13d,%edx
  mov    0xc(%rsp),%ebx
  mov    %ebx,%esi
  mov    %ebx,%edi
  call   <mpz_invert@plt>
  mov    %ebx,%edx
  mov    0x8(%rsp),%ebp
  mov    %ebp,%esi
  mov    %ebp,%edi
  call   <mpz_mul@plt>
  mov    %r13d,%edx
  mov    %ebp,%esi
  mov    %ebp,%edi
  call   <mpz_mod@plt>
  mov    %ebx,%edx
  mov    %ebx,%esi
  mov    %ebx,%edi
  call   <mpz_cdiv_q@plt>
  mov    %r13d,%edx
  mov    0x14(%rsp),%r15d
  mov    %r15d,%esi
  mov    %r15d,%edi
  call   <mpz_invert@plt>
  mov    %r15d,%edx
  mov    0x10(%rsp),%r14d
  mov    %r14d,%esi
  mov    %r14d,%edi
  call   <mpz_mul@plt>
  mov    %r13d,%edx
  mov    %r14d,%esi
  mov    %r14d,%edi
  call   <mpz_mod@plt>
  mov    %r15d,%edx
  mov    %r15d,%esi
  mov    %r15d,%edi
  call   <mpz_cdiv_q@plt>
  lea    D78(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    %ebp,%esi
  lea    D81(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    %ebx,%esi
  lea    D39(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    %r14d,%esi
  lea    D35(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    %ebx,%esi
  lea    D56(%rip),%rdi
  mov    $0x0,%eax
  call   <gmp_printf@plt>
  mov    $0x0,%r13d
  mov    %r13d,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%r12d
  mov    %r12d,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%r14d
  mov    %r14d,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%r15d
  mov    %r15d,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%ebx
  mov    %ebx,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%ebp
  mov    %ebp,%edi
  call   <mpz_clear@plt>
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L24:
  mov    $0x0,%edx
  mov    %r15d,%esi
  mov    0x8(%rsp),%edi
  call   <mpz_add_ui@plt>
  mov    $0x0,%edx
  mov    $0x0,%esi
  mov    0xc(%rsp),%edi
  call   <mpz_add_ui@plt>
  mov    $0x0,%edx
  mov    $0x0,%ebx
  mov    %ebx,%esi
  mov    0x10(%rsp),%edi
  call   <mpz_add_ui@plt>
  mov    $0x0,%edx
  mov    %ebp,%esi
  mov    0x14(%rsp),%edi
  call   <mpz_add_ui@plt>
  jmp    L18
L12:
  mov    $0x0,%edx
  mov    $0x0,%ebx
  mov    %ebx,%esi
  mov    0x8(%rsp),%edi
  call   <mpz_add_ui@plt>
  mov    $0x0,%edx
  mov    $0x0,%ebp
  mov    %ebp,%esi
  mov    0xc(%rsp),%edi
  call   <mpz_add_ui@plt>
  mov    $0x0,%edx
  mov    $0x0,%r15d
  mov    %r15d,%esi
  mov    0x10(%rsp),%edi
  call   <mpz_add_ui@plt>
  mov    $0x0,%edx
  mov    $0x0,%esi
  mov    0x14(%rsp),%edi
  call   <mpz_add_ui@plt>
  jmp    L18
```

tool_calls: name: retrieve_data
arguments: data_label: D34
type: string
name: retrieve_data
arguments: data_label: D81
type: string
name: retrieve_data
arguments: data_label: D39
type: string
name: retrieve_data
arguments: data_label: D35
type: string
name: retrieve_data
arguments: data_label: D56
type: string
name: retrieve_data
arguments: data_label: D78
type: string

tool: D34: 
 VALORES con Reduccion


tool: D81:  Xp = %Zd


tool: D39:  Zp = %Zd


tool: D35:  Xq = %Zd


tool: D56:  Zq = %Zd


tool: D78: 
 VALORES en Coordenadas Afines


assistant: ```c
void montgomery_ladder(mpz_t Xp, mpz_t Zp, mpz_t Xq, mpz_t Zq, mpz_t P, mpz_t a, mpz_t b, mpz_t xd, int R) {
  mpz_t R0, R1, R2, R3, R4, R5, R6, R7;
  mpz_init(R0);
  mpz_init(R1);
  mpz_init(R2);
  mpz_init(R3);
  mpz_init(R4);
  mpz_init(R5);
  mpz_init(R6);
  mpz_init(R7);
  mpz_set(R0, Xp);
  mpz_set(R1, Zp);
  mpz_set(R2, Xq);
  mpz_set(R3, Zq);
  mpz_mul(R6, R2, R1);
  mpz_mul(R7, R3, R0);
  mpz_add(R4, R7, R6);
  mpz_sub(R5, R7, R6);
  mpz_mul(R5, R5, R5);
  mpz_mul(R7, R1, R3);
  mpz_mul(R1, a, R7);
  mpz_mul(R6, R7, R7);
  mpz_mul(R0, R0, R2);
  mpz_mul(R6, b, R6);
  mpz_add(R0, R0, R1);
  mpz_add(R6, R6, R6);
  mpz_mul(R0, R0, R4);
  mpz_mul(R1, xd, R5);
  mpz_add(R4, R0, R6);
  mpz_add(R4, R4, R4);
  mpz_add(R6, R2, R2);
  mpz_sub(R4, R4, R1);
  mpz_add(R7, R3, R3);
  mpz_mul(R0, R6, R7);
  mpz_mul(R1, R3, R3);
  mpz_mul(R2, R2, R2);
  mpz_mul(R3, a, R1);
  mpz_sub(R6, R2, R3);
  mpz_add(R7, R2, R3);
  mpz_add(R1, R1, R1);
  mpz_mul(R2, b, R1);
  mpz_mul(R7, R7, R0);
  mpz_mul(R1, R2, R1);
  mpz_mul(R0, R0, R2);
  mpz_mul(R6, R6, R6);
  mpz_sub(R6, R6, R0);
  mpz_add(R7, R7, R1);
  mpz_mod(R4, R4, P);
  mpz_mod(R5, R5, P);
  mpz_mod(R6, R6, P);
  mpz_mod(R7, R7, P);
  gmp_printf("\n VALORES con Reduccion\n");
  gmp_printf(" Xp = %Zd\n", Xp);
  gmp_printf(" Zp = %Zd\n", Zp);
  gmp_printf(" Xq = %Zd\n", Xq);
  gmp_printf(" Zq = %Zd\n", Zp);
  if (R == 1) {
    mpz_add_ui(Xp, R4, 0);
    mpz_add_ui(Zp, R5, 0);
    mpz_add_ui(Xq, R6, 0);
    mpz_add_ui(Zq, R7, 0);
  }
  if (R == 2) {
    mpz_add_ui(Xp, R6, 0);
    mpz_add_ui(Zp, R7, 0);
    mpz_add_ui(Xq, R4, 0);
    mpz_add_ui(Zq, R5, 0);
  }
  mpz_invert(Zp, Zp, P);
  mpz_mul(Xp, Xp, Zp);
  mpz_mod(Xp, Xp, P);
  mpz_cdiv_q(Zp, Zp, Zp);
  mpz_invert(Zq, Zq, P);
  mpz_mul(Xq, Xq, Zq);
  mpz_mod(Xq, Xq, P);
  mpz_cdiv_q(Zq, Zq, Zq);
  gmp_printf("\n VALORES en Coordenadas Afines\n");
  gmp_printf(" Xp = %Zd\n", Xp);
  gmp_printf(" Zp = %Zd\n", Zp);
  gmp_printf(" Xq = %Zd\n", Xq);
  gmp_printf(" Zq = %Zd\n", Zp);
  mpz_clear(R0);
  mpz_clear(R1);
  mpz_clear(R2);
  mpz_clear(R3);
  mpz_clear(R4);
  mpz_clear(R5);
  mpz_clear(R6);
  mpz_clear(R7);
}
```