user: What is the c source code of the assembly code below?

```asm
<mpqs_sqrt>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %edi,-0x24(%rbp)
  mov    %esi,-0x28(%rbp)
  mov    %edx,-0x2c(%rbp)
  mov    -0x28(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  je     L52
  mov    -0x28(%rbp),%eax
  add    $0x1,%eax
  sar    $0x2,%eax
  mov    %eax,%ecx
  mov    -0x28(%rbp),%edx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpqs_powmod@plt>
  jmp    L73
L52:
  mov    -0x28(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  je     L0
  mov    -0x28(%rbp),%eax
  add    $0x3,%eax
  sar    $0x3,%eax
  mov    %eax,%ecx
  mov    -0x28(%rbp),%edx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpqs_powmod@plt>
  mov    %eax,-0x10(%rbp)
  mov    -0x10(%rbp),%eax
  imul   %eax,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  cmp    -0x24(%rbp),%eax
  jne    L33
  mov    -0x10(%rbp),%eax
  jmp    L73
L33:
  mov    -0x10(%rbp),%eax
  imul   -0x2c(%rbp),%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x10(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0x10(%rbp)
  mov    -0x10(%rbp),%eax
  jmp    L73
L0:
  movl   $0x0,-0x20(%rbp)
  mov    -0x28(%rbp),%eax
  sub    $0x1,%eax
  mov    %eax,-0x1c(%rbp)
  jmp    L18
L53:
  addl   $0x1,-0x20(%rbp)
  sarl   -0x1c(%rbp)
L18:
  mov    -0x1c(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L53
  mov    -0x2c(%rbp),%eax
  mov    %eax,-0xc(%rbp)
  mov    -0x1c(%rbp),%eax
  sar    %eax
  mov    %eax,%ecx
  mov    -0x28(%rbp),%edx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpqs_powmod@plt>
  mov    %eax,-0x8(%rbp)
  mov    -0x8(%rbp),%eax
  imul   %eax,%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  imul   -0x24(%rbp),%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  imul   -0x24(%rbp),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x8(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0x8(%rbp)
  jmp    L142
L44:
  mov    -0x4(%rbp),%eax
  mov    %eax,-0x10(%rbp)
  movl   $0x0,-0x18(%rbp)
  jmp    L67
L48:
  mov    -0x10(%rbp),%eax
  imul   %eax,%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x10(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0x10(%rbp)
  addl   $0x1,-0x18(%rbp)
L67:
  mov    -0x18(%rbp),%eax
  cmp    -0x20(%rbp),%eax
  jge    L89
  cmpl   $0x1,-0x10(%rbp)
  jne    L48
L89:
  mov    -0x18(%rbp),%eax
  add    $0x1,%eax
  mov    %eax,-0x14(%rbp)
  jmp    L16
L30:
  mov    -0xc(%rbp),%eax
  imul   %eax,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0xc(%rbp)
  addl   $0x1,-0x14(%rbp)
L16:
  mov    -0x14(%rbp),%eax
  cmp    -0x20(%rbp),%eax
  jl     L30
  mov    -0x8(%rbp),%eax
  imul   -0xc(%rbp),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x8(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0x8(%rbp)
  mov    -0xc(%rbp),%eax
  imul   %eax,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0xc(%rbp)
  mov    -0x4(%rbp),%eax
  imul   -0xc(%rbp),%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %edx,-0x4(%rbp)
  mov    -0x18(%rbp),%eax
  mov    %eax,-0x20(%rbp)
L142:
  cmpl   $0x1,-0x4(%rbp)
  jne    L44
  mov    -0x8(%rbp),%eax
L73:
  leave
  ret
```

assistant: ```c
ushort mpqs_sqrt(ushort a, ushort p, ushort help) {
  ushort e, u, i, l;
  ulong b, g, r, k;
  if (p & 2)
    return mpqs_powmod(a, (p + 1) >> 2, p);
  if (p & 4) {
    b = mpqs_powmod(a, (p + 3) >> 3, p);
    g = b * b;
    g %= (ulong)p;
    if (g == a)
      return b;
    b *= (ulong)help;
    b %= (ulong)p;
    return b;
  }
  e = 0;
  u = p - 1;
  while (!(u & 1)) {
    e++;
    u >>= 1;
  }
  g = help;
  r = mpqs_powmod(a, u >> 1, p);
  k = r * r;
  k %= (ulong)p;
  k *= a;
  k %= (ulong)p;
  r *= a;
  r %= (ulong)p;
  while (k != 1) {
    b = k;
    for (i = 0; i < e && b != 1; i++) {
      b *= b;
      b %= (ulong)p;
    }
    for (l = i + 1; l < e; l++) {
      g *= g;
      g %= (ulong)p;
    }
    r *= g;
    r %= (ulong)p;
    g *= g;
    g %= (ulong)p;
    k *= g;
    k %= (ulong)p;
    e = i;
  }
  return (ushort)r;
}
```