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

```asm
<X509_cmp_time>:
  endbr64
  push   %r15
  push   %r14
  mov    %rsi,%r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  sub    $0x68,%rsp
  mov    D5(%rip),%r13
  mov    (%rdi),%ebp
  mov    %fs:0x28,%rax
  mov    %rax,0x58(%rsp)
  xor    %eax,%eax
  mov    0x8(%rdi),%r12
  mov    0x0(%r13),%rax
  cmp    %rax,0x10(%rdi)
  je     L158
  lea    -0xd(%rbp),%eax
  cmp    $0xa,%eax
  jbe    L182
L131:
  xor    %eax,%eax
L17:
  mov    0x58(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L18
  add    $0x68,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L182:
  lea    0x20(%rsp),%r15
  mov    %r12,%rsi
  mov    $0xc,%edx
  sub    $0xc,%ebp
  mov    %r15,%rdi
  add    $0xc,%r12
  call   <memcpy@plt>
  lea    0x2c(%rsp),%rax
L245:
  movzbl (%r12),%edx
  lea    -0x2b(%rdx),%ecx
  and    $0xfd,%ecx
  je     L233
  cmp    $0x5a,%dl
  jne    L367
L233:
  mov    $0x3030,%ecx
  lea    0x2(%rax),%rdx
  mov    %cx,(%rax)
L12:
  mov    $0x5a,%eax
  mov    %ax,(%rdx)
L251:
  movzbl (%r12),%eax
  cmp    $0x5a,%al
  je     L334
  lea    -0x2b(%rax),%edx
  and    $0xfd,%edx
  jne    L131
  cmp    $0x5,%ebp
  jne    L131
  movzbl 0x1(%r12),%ecx
  lea    -0x30(%rcx),%edx
  cmp    $0x9,%dl
  ja     L131
  movzbl 0x2(%r12),%ecx
  sub    $0x30,%ecx
  cmp    $0x9,%cl
  ja     L131
  movzbl 0x3(%r12),%esi
  sub    $0x30,%esi
  cmp    $0x9,%sil
  ja     L131
  movzbl 0x4(%r12),%edi
  sub    $0x30,%edi
  cmp    $0x9,%dil
  ja     L131
  movsbl %dl,%edx
  movsbl %cl,%ecx
  movsbl %sil,%esi
  movsbl %dil,%edi
  lea    (%rdx,%rdx,4),%edx
  lea    (%rcx,%rdx,2),%ecx
  lea    (%rsi,%rsi,4),%edx
  imul   $0x3c,%ecx,%ecx
  lea    (%rdi,%rdx,2),%edx
  movslq %edx,%rdx
  movslq %ecx,%rcx
  add    %rcx,%rdx
  cmp    $0x2d,%al
  mov    %rdx,%rax
  je     L130
  shl    $0x4,%rax
  sub    %rdx,%rax
  lea    0x0(,%rax,4),%rsi
  jmp    L317
  nop
L158:
  lea    -0xb(%rbp),%eax
  cmp    $0x6,%eax
  ja     L131
  lea    0x20(%rsp),%r15
  mov    %r12,%rsi
  mov    $0xa,%edx
  sub    $0xa,%ebp
  mov    %r15,%rdi
  add    $0xa,%r12
  call   <memcpy@plt>
  lea    0x2a(%rsp),%rax
  jmp    L245
  nopw   0x0(%rax,%rax,1)
L367:
  cmp    $0x1,%ebp
  je     L131
  mov    %dl,(%rax)
  movzbl 0x1(%r12),%ecx
  lea    0x2(%rax),%rdx
  mov    %cl,0x1(%rax)
  mov    %ebp,%ecx
  sub    $0x2,%ecx
  je     L131
  cmpb   $0x2e,0x2(%r12)
  je     L76
  add    $0x2,%r12
  mov    %ecx,%ebp
  jmp    L12
  xchg   %ax,%ax
L334:
  xor    %esi,%esi
  cmp    $0x1,%ebp
  jne    L131
L317:
  mov    0x10(%rbx),%rax
  lea    0x40(%rsp),%rbp
  mov    %rsp,%rdi
  mov    %r14,%rdx
  movq   $0x0,0x18(%rsp)
  mov    %rax,0x10(%rsp)
  movl   $0x18,(%rsp)
  mov    %rbp,0x8(%rsp)
  call   <X509_time_adj@plt>
  test   %rax,%rax
  je     L131
  mov    0x0(%r13),%rax
  cmp    %rax,0x10(%rbx)
  je     L260
L347:
  mov    %rbp,%rsi
  mov    %r15,%rdi
  call   <strcmp@plt>
  test   %eax,%eax
  jne    L17
L128:
  or     $0xffffffff,%eax
  jmp    L17
  nopl   0x0(%rax,%rax,1)
L76:
  mov    %ebp,%edi
  lea    0x3(%r12),%rsi
  sub    $0x3,%edi
  je     L131
  movzbl 0x3(%r12),%ecx
  sub    $0x30,%ecx
  cmp    $0x9,%cl
  ja     L328
  mov    %ebp,%edi
  lea    0x4(%r12),%rsi
  sub    $0x4,%edi
  je     L131
  movzbl 0x4(%r12),%ecx
  sub    $0x30,%ecx
  cmp    $0x9,%cl
  ja     L328
  mov    %ebp,%edi
  lea    0x5(%r12),%rsi
  sub    $0x5,%edi
  je     L131
  movzbl 0x5(%r12),%ecx
  sub    $0x30,%ecx
  cmp    $0x9,%cl
  ja     L328
  mov    $0x5a,%edx
  add    $0x6,%r12
  mov    %dx,0x2(%rax)
  sub    $0x6,%ebp
  je     L131
  jmp    L251
  nopl   (%rax)
L260:
  movsbl 0x20(%rsp),%eax
  lea    -0xf0(%rax,%rax,4),%edx
  movsbl 0x21(%rsp),%eax
  lea    -0x30(%rax,%rdx,2),%edx
  lea    0x64(%rdx),%eax
  cmp    $0x32,%edx
  cmovl  %eax,%edx
  movsbl 0x40(%rsp),%eax
  lea    -0xf0(%rax,%rax,4),%ecx
  movsbl 0x41(%rsp),%eax
  lea    -0x30(%rax,%rcx,2),%eax
  lea    0x64(%rax),%ecx
  cmp    $0x32,%eax
  cmovl  %ecx,%eax
  cmp    %eax,%edx
  jl     L128
  mov    $0x1,%eax
  jle    L347
  jmp    L17
L328:
  mov    %edi,%ebp
  mov    %rsi,%r12
  jmp    L12
L130:
  shl    $0x4,%rax
  sub    %rax,%rdx
  lea    0x0(,%rdx,4),%rsi
  jmp    L317
L18:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) {
  char *str;
  ASN1_TIME atm;
  long offset;
  char buff1[24], buff2[24], *p;
  int i, j, remaining;
  p = buff1;
  remaining = ctm->length;
  str = (char *)ctm->data;
  if (ctm->type == V_ASN1_UTCTIME) {
    int min_length = sizeof("YYMMDDHHMMZ") - 1;
    int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
    if (remaining < min_length || remaining > max_length)
      return 0;
    memcpy(p, str, 10);
    p += 10;
    str += 10;
    remaining -= 10;
  } else {
    int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
    int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
    if (remaining < min_length || remaining > max_length)
      return 0;
    memcpy(p, str, 12);
    p += 12;
    str += 12;
    remaining -= 12;
  }
  if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
    *(p++) = '0';
    *(p++) = '0';
  } else {
    if (remaining < 2)
      return 0;
    *(p++) = *(str++);
    *(p++) = *(str++);
    remaining -= 2;
    if (remaining && *str == '.') {
      str++;
      remaining--;
      for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
        if (*str < '0' || *str > '9')
          break;
      }
    }
  }
  *(p++) = 'Z';
  *(p++) = '\0';
  if (!remaining)
    return 0;
  if (*str == 'Z') {
    if (remaining != 1)
      return 0;
    offset = 0;
  } else {
    if ((*str != '+') && (*str != '-'))
      return 0;
    if (remaining != 5)
      return 0;
    if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
      return 0;
    offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
    offset += (str[3] - '0') * 10 + (str[4] - '0');
    if (*str == '-')
      offset = -offset;
  }
  atm.type = ctm->type;
  atm.flags = 0;
  atm.length = sizeof(buff2);
  atm.data = (unsigned char *)buff2;
  if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
    return 0;
  if (ctm->type == V_ASN1_UTCTIME) {
    i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
    if (i < 50)
      i += 100;
    j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
    if (j < 50)
      j += 100;
    if (i < j)
      return -1;
    if (i > j)
      return 1;
  }
  i = strcmp(buff1, buff2);
  if (i == 0)
    return -1;
  else
    return i;
}
```