user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<do_ext_i2d>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %esi,-0x3c(%rbp)
  mov    %edx,-0x40(%rbp)
  mov    %rcx,-0x48(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movq   $0x0,-0x18(%rbp)
  mov    -0x38(%rbp),%rax
  mov    0x8(%rax),%rax
  test   %rax,%rax
  je     L30
  movq   $0x0,-0x28(%rbp)
  mov    -0x38(%rbp),%rax
  mov    0x8(%rax),%rax
  mov    %rax,%rdi
  call   <ASN1_ITEM_ptr@plt>
  mov    %eax,%edx
  lea    -0x28(%rbp),%rcx
  mov    -0x48(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <ASN1_item_i2d@plt>
  mov    %eax,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  jns    L32
  jmp    L55
L30:
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x48(%rbp),%rax
  mov    $0x0,%esi
  mov    %rax,%rdi
  call   *%rdx
  mov    %eax,-0x2c(%rbp)
  mov    -0x2c(%rbp),%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,-0x28(%rbp)
  mov    -0x28(%rbp),%rax
  test   %rax,%rax
  je     L11
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x38(%rbp),%rax
  mov    (%rax),%rcx
  lea    -0x20(%rbp),%rdx
  mov    -0x48(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   *%rcx
L32:
  mov    $0x0,%eax
  call   <ASN1_OCTET_STRING_new@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L81
  mov    -0x28(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x18(%rbp),%rax
  mov    -0x2c(%rbp),%edx
  mov    %edx,0x8(%rax)
  mov    -0x18(%rbp),%rcx
  mov    -0x40(%rbp),%edx
  mov    -0x3c(%rbp),%eax
  mov    %eax,%esi
  mov    $0x0,%edi
  call   <X509_EXTENSION_create_by_NID@plt>
  mov    %rax,-0x10(%rbp)
  cmpq   $0x0,-0x10(%rbp)
  je     L0
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <ASN1_OCTET_STRING_free@plt>
  mov    -0x10(%rbp),%rax
  jmp    L13
L11:
  nop
  jmp    L55
L81:
  nop
  jmp    L55
L0:
  nop
L55:
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <ASN1_OCTET_STRING_free@plt>
  mov    D19(%rip),%rax
  mov    (%rax),%edx
  mov    D12(%rip),%rax
  mov    (%rax),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <X509V3err@plt>
  mov    $0x0,%eax
L13:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L65
  call   <__stack_chk_fail@plt>
L65:
  leave
  ret
```

assistant: ```c
X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, void *ext_struc) {
  unsigned char *ext_der;
  int ext_len;
  ASN1_OCTET_STRING *ext_oct = NULL;
  X509_EXTENSION *ext;
  if (method->it) {
    ext_der = NULL;
    ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
    if (ext_len < 0)
      goto merr;
  } else {
    unsigned char *p;
    ext_len = method->i2d(ext_struc, NULL);
    if (!(ext_der = malloc(ext_len)))
      goto merr;
    p = ext_der;
    method->i2d(ext_struc, &p);
  }
  if (!(ext_oct = ASN1_OCTET_STRING_new()))
    goto merr;
  ext_oct->data = ext_der;
  ext_oct->length = ext_len;
  ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
  if (!ext)
    goto merr;
  ASN1_OCTET_STRING_free(ext_oct);
  return ext;
merr:
  ASN1_OCTET_STRING_free(ext_oct);
  X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE);
  return NULL;
}
```