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

```asm
<point_math_inversemod>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %edi,0x1c(%rsp)
  mov    %esi,%r15d
  mov    %edx,0x18(%rsp)
  mov    $0x0,%ebx
  mov    %ebx,%edi
  call   <mpz_init@plt>
  mov    $0x0,%ebp
  mov    %ebp,%edi
  call   <mpz_init@plt>
  mov    $0x0,%edi
  call   <mpz_init@plt>
  mov    $0x0,%edi
  call   <mpz_init@plt>
  mov    $0x0,%r14d
  mov    %r14d,%edi
  call   <mpz_init@plt>
  mov    $0x0,%edi
  call   <mpz_init@plt>
  mov    $0x0,%r12d
  mov    %r12d,%edi
  call   <mpz_init@plt>
  mov    $0x0,%r13d
  mov    %r13d,%edi
  call   <mpz_init@plt>
  mov    %r12d,%edi
  call   <mpz_init@plt>
  mov    %ebp,%edi
  call   <mpz_init@plt>
  mov    $0x0,%edi
  call   <mpz_init@plt>
  mov    $0x0,%edi
  call   <mpz_init@plt>
  mov    %ebx,%edi
  call   <mpz_init@plt>
  jmp    L40
L58:
  mov    0x18(%rsp),%edx
  mov    %r15d,%esi
  mov    %r15d,%edi
  call   <mpz_add@plt>
L40:
  mov    $0x0,%esi
  mov    %r15d,%edi
  call   <mpz_cmp_ui@plt>
  test   %rax,%rax
  js     L58
  mov    $0x0,%esi
  mov    %r15d,%edi
  call   <mpz_cmp_ui@plt>
  test   %rax,%rax
  js     L31
  mov    %r15d,%esi
  mov    0x18(%rsp),%edi
  call   <mpz_cmp@plt>
  test   %rax,%rax
  jg     L46
L31:
  mov    0x18(%rsp),%edx
  mov    %r15d,%esi
  mov    %r15d,%edi
  call   <mpz_mod@plt>
L46:
  mov    %r15d,%esi
  mov    $0x0,%ebx
  mov    %ebx,%edi
  call   <mpz_set@plt>
  mov    0x18(%rsp),%esi
  mov    $0x0,%ebp
  mov    %ebp,%edi
  call   <mpz_set@plt>
  mov    $0x1,%esi
  mov    $0x0,%edi
  call   <mpz_set_ui@plt>
  mov    $0x0,%esi
  mov    $0x0,%edi
  call   <mpz_set_ui@plt>
  mov    $0x0,%esi
  mov    $0x0,%r14d
  mov    %r14d,%edi
  call   <mpz_set_ui@plt>
  mov    $0x1,%esi
  mov    $0x0,%edi
  call   <mpz_set_ui@plt>
  jmp    L21
L11:
  mov    $0x0,%ebx
  mov    %ebx,%edx
  mov    $0x0,%ebp
  mov    %ebp,%esi
  mov    $0x0,%r13d
  mov    %r13d,%edi
  call   <mpz_tdiv_q@plt>
  mov    %ebx,%edx
  mov    %ebp,%esi
  mov    $0x0,%r12d
  mov    %r12d,%edi
  call   <mpz_mod@plt>
  mov    %ebx,%esi
  mov    %ebp,%edi
  call   <mpz_set@plt>
  mov    %r12d,%esi
  mov    %ebx,%edi
  call   <mpz_set@plt>
  mov    $0x0,%eax
  mov    %eax,0x8(%rsp)
  mov    %eax,%esi
  mov    %r12d,%edi
  call   <mpz_set@plt>
  mov    $0x0,%eax
  mov    %eax,0xc(%rsp)
  mov    %eax,%esi
  mov    %ebp,%edi
  call   <mpz_set@plt>
  mov    $0x0,%r14d
  mov    %r14d,%esi
  mov    $0x0,%eax
  mov    %eax,0x14(%rsp)
  mov    %eax,%edi
  call   <mpz_set@plt>
  mov    $0x0,%eax
  mov    %eax,0x10(%rsp)
  mov    %eax,%esi
  mov    $0x0,%r15d
  mov    %r15d,%edi
  call   <mpz_set@plt>
  mov    %r12d,%edx
  mov    %r13d,%esi
  mov    %ebx,%edi
  call   <mpz_mul@plt>
  mov    %ebx,%edx
  mov    0x14(%rsp),%esi
  mov    0x8(%rsp),%edi
  call   <mpz_sub@plt>
  mov    %ebp,%edx
  mov    %r13d,%esi
  mov    %ebx,%edi
  call   <mpz_mul@plt>
  mov    %ebx,%edx
  mov    %r15d,%esi
  mov    0xc(%rsp),%edi
  call   <mpz_sub@plt>
  mov    %r12d,%esi
  mov    %r14d,%edi
  call   <mpz_set@plt>
  mov    %ebp,%esi
  mov    0x10(%rsp),%edi
  call   <mpz_set@plt>
L21:
  mov    $0x0,%esi
  mov    $0x0,%ebx
  mov    %ebx,%edi
  call   <mpz_cmp_ui@plt>
  test   %rax,%rax
  jne    L11
  mov    $0x0,%esi
  mov    $0x0,%r14d
  mov    %r14d,%edi
  call   <mpz_cmp_ui@plt>
  test   %rax,%rax
  jle    L37
  mov    %r14d,%esi
  mov    0x1c(%rsp),%edi
  call   <mpz_set@plt>
L30:
  mov    $0x0,%ebx
  mov    %ebx,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%ebp
  mov    %ebp,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%r14d
  mov    %r14d,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%r12d
  mov    %r12d,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%r13d
  mov    %r13d,%edi
  call   <mpz_clear@plt>
  mov    %r12d,%edi
  call   <mpz_clear@plt>
  mov    %ebp,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%edi
  call   <mpz_clear@plt>
  mov    $0x0,%edi
  call   <mpz_clear@plt>
  mov    %ebx,%edi
  call   <mpz_clear@plt>
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L37:
  mov    0x18(%rsp),%edx
  mov    $0x0,%r14d
  mov    %r14d,%esi
  mov    0x1c(%rsp),%edi
  call   <mpz_add@plt>
  jmp    L30
```

assistant: ```c
void point_math_inversemod(mpz_t r, mpz_t a, mpz_t m) {
  mpz_t c, d, uc, vc, ud, vd, rem, q, uct, vct, udt, vdt, temp;
  mpz_init(c);
  mpz_init(d);
  mpz_init(uc);
  mpz_init(vc);
  mpz_init(ud);
  mpz_init(vd);
  mpz_init(rem);
  mpz_init(q);
  mpz_init(uct);
  mpz_init(vct);
  mpz_init(udt);
  mpz_init(vdt);
  mpz_init(temp);
  while (mpz_cmp_ui(a, 0) < 0) {
    mpz_add(a, a, m);
  }
  if (mpz_cmp_ui(a, 0) < 0 || mpz_cmp(m, a) <= 0) {
    mpz_mod(a, a, m);
  }
  mpz_set(c, a);
  mpz_set(d, m);
  mpz_set_ui(uc, 1);
  mpz_set_ui(vc, 0);
  mpz_set_ui(ud, 0);
  mpz_set_ui(vd, 1);
  while (mpz_cmp_ui(c, 0) != 0) {
    mpz_tdiv_q(q, d, c);
    mpz_mod(rem, d, c);
    mpz_set(d, c);
    mpz_set(c, rem);
    mpz_set(uct, uc);
    mpz_set(vct, vc);
    mpz_set(udt, ud);
    mpz_set(vdt, vd);
    mpz_mul(temp, q, uct);
    mpz_sub(uc, udt, temp);
    mpz_mul(temp, q, vct);
    mpz_sub(vc, vdt, temp);
    mpz_set(ud, uct);
    mpz_set(vd, vct);
  }
  if (mpz_cmp_ui(ud, 0) > 0) {
    mpz_set(r, ud);
  } else {
    mpz_add(r, ud, m);
  }
  mpz_clear(c);
  mpz_clear(d);
  mpz_clear(uc);
  mpz_clear(vc);
  mpz_clear(ud);
  mpz_clear(vd);
  mpz_clear(rem);
  mpz_clear(q);
  mpz_clear(uct);
  mpz_clear(vct);
  mpz_clear(udt);
  mpz_clear(vdt);
  mpz_clear(temp);
}
```