user: 请从给定的汇编指令推导出C源代码：

```asm
<GetECKeyPrivate>:
  endbr64
  push   %r15
  push   %r14
  mov    %r9,%r14
  push   %r13
  mov    %edx,%r13d
  push   %r12
  mov    %rsi,%r12
  mov    %r8d,%esi
  push   %rbp
  mov    %rdi,%rbp
  mov    %rcx,%rdi
  push   %rbx
  sub    $0x18,%rsp
  mov    0x58(%rsp),%ebx
  test   %rbp,%rbp
  je     L237
L227:
  xor    %edx,%edx
  call   <BN_bin2bn@plt>
  mov    0x50(%rsp),%esi
  mov    %r14,%rdi
  xor    %edx,%edx
  mov    %rax,%r15
  call   <BN_bin2bn@plt>
  mov    %r13d,%esi
  xor    %edx,%edx
  mov    %r12,%rdi
  mov    %rax,%r14
  call   <BN_bin2bn@plt>
  mov    %rax,%r13
  test   %r15,%r15
  je     L206
  test   %r14,%r14
  je     L54
  test   %rax,%rax
  je     L39
  mov    %rax,%rsi
  mov    %rbp,%rdi
  call   <EC_KEY_set_private_key@plt>
  test   %eax,%eax
  je     L231
  test   %ebx,%ebx
  je     L11
  cmp    $0x1,%ebx
  jne    L196
  xor    %eax,%eax
  call   <sm2_ec_group2@plt>
  mov    %rax,%r12
L12:
  test   %r12,%r12
  je     L31
  mov    %r12,%rsi
  mov    %rbp,%rdi
  call   <EC_KEY_set_group@plt>
  test   %eax,%eax
  je     L254
  mov    %r12,%rdi
  call   <EC_POINT_new@plt>
  mov    %rax,%rbx
  test   %rax,%rax
  je     L3
  xor    %r8d,%r8d
  mov    %r14,%rcx
  mov    %r15,%rdx
  mov    %rax,%rsi
  mov    %r12,%rdi
  call   <EC_POINT_set_affine_coordinates_GFp@plt>
  test   %eax,%eax
  je     L156
  xor    %edx,%edx
  mov    %rbx,%rsi
  mov    %r12,%rdi
  call   <EC_POINT_is_on_curve@plt>
  test   %eax,%eax
  je     L112
  mov    %rbx,%rsi
  mov    %rbp,%rdi
  call   <EC_KEY_set_public_key@plt>
  test   %eax,%eax
  je     L258
  mov    %rbp,%rdi
  call   <EC_KEY_check_key@plt>
  mov    %r15,%rdi
  test   %eax,%eax
  je     L170
  call   <BN_free@plt>
  mov    %r14,%rdi
  xor    %r12d,%r12d
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  mov    %rbx,%rdi
  call   <EC_POINT_free@plt>
L59:
  add    $0x18,%rsp
  mov    %r12d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  xchg   %ax,%ax
L11:
  xor    %eax,%eax
  call   <sm2_ec_group@plt>
  mov    %rax,%r12
  jmp    L12
  nop
L237:
  xor    %eax,%eax
  mov    %r8d,0xc(%rsp)
  mov    %rcx,(%rsp)
  call   <EC_KEY_new@plt>
  mov    0xc(%rsp),%esi
  mov    (%rsp),%rdi
  mov    %rax,%rbp
  jmp    L227
L54:
  test   %r15,%r15
  je     L206
  nopl   (%rax)
L39:
  mov    %r15,%rdi
  call   <BN_free@plt>
L206:
  test   %r14,%r14
  je     L70
  mov    %r14,%rdi
  call   <BN_free@plt>
L70:
  mov    $0xffffffff,%r12d
  test   %r13,%r13
  je     L59
  mov    %r13,%rdi
  call   <BN_free@plt>
  jmp    L59
  nopw   0x0(%rax,%rax,1)
L196:
  mov    %r15,%rdi
  mov    $0xfffffff6,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  jmp    L59
L254:
  mov    %r15,%rdi
  mov    $0xfffffffc,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  jmp    L59
L156:
  mov    %r15,%rdi
  mov    $0xfffffffa,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  mov    %rbx,%rdi
  call   <EC_POINT_free@plt>
  jmp    L59
L112:
  mov    %r15,%rdi
  mov    $0xfffffff9,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  mov    %rbx,%rdi
  call   <EC_POINT_free@plt>
  jmp    L59
L258:
  mov    %r15,%rdi
  mov    $0xfffffff8,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  mov    %rbx,%rdi
  call   <EC_POINT_free@plt>
  jmp    L59
L170:
  call   <BN_free@plt>
  mov    %r14,%rdi
  mov    $0xfffffff7,%r12d
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  mov    %rbx,%rdi
  call   <EC_POINT_free@plt>
  jmp    L59
L231:
  mov    %r15,%rdi
  mov    $0xfffffffe,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  jmp    L59
L3:
  mov    %r15,%rdi
  mov    $0xfffffffb,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  jmp    L59
L31:
  mov    %r15,%rdi
  mov    $0xfffffffd,%r12d
  call   <BN_free@plt>
  mov    %r14,%rdi
  call   <BN_free@plt>
  mov    %r13,%rdi
  call   <BN_free@plt>
  jmp    L59
```

assistant: ```c
int GetECKeyPrivate(EC_KEY *ec_key, unsigned char *privD, int privDlen, unsigned char *pubX, int pubXlen, unsigned char *pubY, int pubYlen, int ctype) {
  if (!ec_key)
    ec_key = EC_KEY_new();
  BIGNUM *pub_key_x = BN_bin2bn(pubX, pubXlen, NULL);
  BIGNUM *pub_key_y = BN_bin2bn(pubY, pubYlen, NULL);
  BIGNUM *priv_key = BN_bin2bn(privD, privDlen, NULL);
  if (!pub_key_x || !pub_key_y || !priv_key) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    return -1;
  }
  if (!EC_KEY_set_private_key(ec_key, priv_key)) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    return -2;
  }
  EC_GROUP *ec_group = NULL;
  if (ctype == 0) {
    ec_group = sm2_ec_group();
  } else if (ctype == 1) {
    ec_group = sm2_ec_group2();
  } else {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    return -10;
  }
  if (!ec_group) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    return -3;
  }
  if (!EC_KEY_set_group(ec_key, ec_group)) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    return -4;
  }
  EC_POINT *pub_key = EC_POINT_new(ec_group);
  if (!pub_key) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    return -5;
  }
  if (!EC_POINT_set_affine_coordinates_GFp(ec_group, pub_key, pub_key_x, pub_key_y, NULL)) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    if (pub_key)
      EC_POINT_free(pub_key);
    return -6;
  }
  if (!EC_POINT_is_on_curve(ec_group, pub_key, NULL)) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    if (pub_key)
      EC_POINT_free(pub_key);
    return -7;
  }
  if (!EC_KEY_set_public_key(ec_key, pub_key)) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    if (pub_key)
      EC_POINT_free(pub_key);
    return -8;
  }
  if (!EC_KEY_check_key(ec_key)) {
    if (pub_key_x)
      BN_free(pub_key_x);
    if (pub_key_y)
      BN_free(pub_key_y);
    if (priv_key)
      BN_free(priv_key);
    if (pub_key)
      EC_POINT_free(pub_key);
    return -9;
  }
  if (pub_key_x)
    BN_free(pub_key_x);
  if (pub_key_y)
    BN_free(pub_key_y);
  if (priv_key)
    BN_free(priv_key);
  if (pub_key)
    EC_POINT_free(pub_key);
  return 0;
}
```