user: Demonstrate the C code that generates the assembly output below:

```asm
<razor_versioncmp>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  cmpq   $0x0,-0x38(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  cmpq   $0x0,-0x40(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  lea    -0x28(%rbp),%rcx
  mov    -0x38(%rbp),%rax
  mov    $0xa,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strtol@plt>
  mov    %rax,-0x18(%rbp)
  lea    -0x20(%rbp),%rcx
  mov    -0x40(%rbp),%rax
  mov    $0xa,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strtol@plt>
  mov    %rax,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x3a,%al
  sete   %al
  movzbl %al,%edx
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x3a,%al
  sete   %al
  movzbl %al,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  mov    %eax,-0x2c(%rbp)
  cmpl   $0x0,-0x2c(%rbp)
  jns    L89
  movq   $0x0,-0x18(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x20(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x20(%rbp)
  jmp    L1
L89:
  cmpl   $0x0,-0x2c(%rbp)
  jle    L1
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x28(%rbp)
  movq   $0x0,-0x10(%rbp)
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x20(%rbp)
L1:
  mov    -0x18(%rbp),%rax
  cmp    -0x10(%rbp),%rax
  je     L19
  mov    -0x18(%rbp),%rax
  mov    %eax,%edx
  mov    -0x10(%rbp),%rax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  jmp    L55
L10:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%edx
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  cmp    %al,%dl
  je     L69
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%edx
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  jmp    L55
L69:
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x20(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L19
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L19
  mov    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <razor_versioncmp>
  jmp    L55
L19:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L84
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L10
L84:
  mov    -0x28(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%edx
  mov    -0x20(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
L55:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L33
  call   <__stack_chk_fail@plt>
L33:
  leave
  ret
```

assistant: ```c
__attribute__((visibility("default"))) int razor_versioncmp(const char *s1, const char *s2) {
  const char *p1, *p2;
  long n1, n2;
  int res;
  assert(s1 != NULL);
  assert(s2 != NULL);
  n1 = strtol(s1, (char **)&p1, 10);
  n2 = strtol(s2, (char **)&p2, 10);
  res = (*p1 == ':') - (*p2 == ':');
  if (res < 0) {
    n1 = 0;
    p1 = s1;
    p2++;
  } else if (res > 0) {
    p1++;
    n2 = 0;
    p2 = s2;
  }
  if (n1 != n2)
    return n1 - n2;
  while (*p1 && *p2) {
    if (*p1 != *p2)
      return *p1 - *p2;
    p1++;
    p2++;
    if (isdigit(*p1) && isdigit(*p2))
      return razor_versioncmp(p1, p2);
  }
  return *p1 - *p2;
}
```