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

```asm
<psys_vercmp>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x58(%rbp)
  mov    %rsi,-0x60(%rbp)
  mov    -0x58(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %eax,-0x40(%rbp)
  mov    -0x58(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %eax,-0x3c(%rbp)
  cmpl   $0x0,-0x40(%rbp)
  jne    L78
  cmpl   $0x0,-0x3c(%rbp)
  jne    L78
  cmpl   $0x0,-0x40(%rbp)
  je     L172
  mov    $0x1,%eax
  jmp    L215
L172:
  cmpl   $0x0,-0x3c(%rbp)
  je     L297
  mov    $0xffffffff,%eax
  jmp    L215
L297:
  mov    $0x0,%eax
  jmp    L215
L78:
  mov    -0x58(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x60(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x30(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jle    L113
  mov    -0x30(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x39,%al
  jg     L113
  mov    $0x1,%eax
  jmp    L199
L113:
  mov    $0x0,%eax
L199:
  mov    %eax,-0x38(%rbp)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jle    L158
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x39,%al
  jg     L158
  mov    $0x1,%eax
  jmp    L218
L158:
  mov    $0x0,%eax
L218:
  mov    %eax,-0x34(%rbp)
  movl   $0x0,-0x44(%rbp)
  mov    -0x38(%rbp),%eax
  cmp    -0x34(%rbp),%eax
  jne    L223
  cmpl   $0x0,-0x38(%rbp)
  je     L243
  jmp    L156
L147:
  addq   $0x1,-0x30(%rbp)
  addq   $0x1,-0x20(%rbp)
L156:
  mov    -0x30(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x30,%al
  je     L147
  jmp    L384
L299:
  addq   $0x1,-0x28(%rbp)
  addq   $0x1,-0x18(%rbp)
L384:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x30,%al
  je     L299
  jmp    L87
L106:
  addq   $0x1,-0x20(%rbp)
L87:
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jle    L121
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x39,%al
  jle    L106
  jmp    L121
L111:
  addq   $0x1,-0x18(%rbp)
L121:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jle    L198
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x39,%al
  jle    L111
  jmp    L198
L28:
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x60,%al
  jg     L292
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x7a,%al
  jg     L352
L292:
  mov    $0x1,%eax
  jmp    L94
L352:
  mov    $0x0,%eax
L94:
  mov    %eax,%edi
  call   <assert@plt>
  addq   $0x1,-0x20(%rbp)
L243:
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L28
  jmp    L280
L130:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x60,%al
  jg     L162
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x7a,%al
  jg     L65
L162:
  mov    $0x1,%eax
  jmp    L188
L65:
  mov    $0x0,%eax
L188:
  mov    %eax,%edi
  call   <assert@plt>
  addq   $0x1,-0x18(%rbp)
L280:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L130
L198:
  mov    -0x20(%rbp),%rax
  sub    -0x30(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x18(%rbp),%rax
  sub    -0x28(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x10(%rbp),%rax
  cmp    %rax,%rdx
  cmovb  %rax,%rdx
  mov    -0x28(%rbp),%rcx
  mov    -0x30(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncmp@plt>
  mov    %eax,-0x44(%rbp)
  jmp    L136
L223:
  cmpl   $0x0,-0x38(%rbp)
  je     L327
  movl   $0x1,-0x44(%rbp)
  jmp    L136
L327:
  movl   $0xffffffff,-0x44(%rbp)
L136:
  cmpl   $0x0,-0x44(%rbp)
  je     L159
  mov    -0x44(%rbp),%eax
  jmp    L215
L159:
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L290
  addq   $0x1,-0x20(%rbp)
L290:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L245
  addq   $0x1,-0x18(%rbp)
L245:
  mov    -0x18(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <psys_vercmp>
L215:
  leave
  ret
```

assistant: ```c
int psys_vercmp(const char *version1, const char *version2) {
  int v1_len, v2_len;
  const char *v1s_start, *v2s_start;
  const char *v1s_end, *v2s_end;
  int v1s_isdigit, v2s_isdigit;
  int diff;
  v1_len = strlen(version1);
  v2_len = strlen(version1);
  if (!v1_len && !v2_len) {
    if (v1_len)
      return 1;
    else if (v2_len)
      return -1;
    else
      return 0;
  }
  v1s_start = v1s_end = version1;
  v2s_start = v2s_end = version2;
  v1s_isdigit = (*v1s_start >= '0' && *v1s_start <= '9');
  v2s_isdigit = (*v2s_start >= '0' && *v2s_start <= '9');
  diff = 0;
  if (v1s_isdigit == v2s_isdigit) {
    size_t v1s_len, v2s_len;
    if (v1s_isdigit) {
      while (*v1s_start == '0') {
        v1s_start++;
        v1s_end++;
      }
      while (*v2s_start == '0') {
        v2s_start++;
        v2s_end++;
      }
      while ((*v1s_end >= '0' && *v1s_end <= '9'))
        v1s_end++;
      while ((*v2s_end >= '0' && *v2s_end <= '9'))
        v2s_end++;
    } else {
      while (*v1s_end) {
        assert((*v1s_end >= 'a' || *v1s_end <= 'z'));
        v1s_end++;
      }
      while (*v2s_end) {
        assert((*v2s_end >= 'a' || *v2s_end <= 'z'));
        v2s_end++;
      }
    }
    v1s_len = v1s_end - v1s_start;
    v2s_len = v2s_end - v2s_start;
    diff = strncmp(v1s_start, v2s_start, (v1s_len > v2s_len) ? v1s_len : v2s_len);
  } else {
    if (v1s_isdigit)
      diff = 1;
    else
      diff = -1;
  }
  if (diff)
    return diff;
  else {
    if (*v1s_end == '.')
      v1s_end++;
    if (*v2s_end == '.')
      v2s_end++;
    return psys_vercmp(v1s_end, v2s_end);
  }
}
```