user: What is the c source code of the assembly code below:

```asm
<strtoul>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %edx,-0x44(%rbp)
  cmpq   $0x0,-0x38(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <assert@plt>
  cmpl   $0x0,-0x44(%rbp)
  je     L243
  cmpl   $0x1,-0x44(%rbp)
  jle    L409
  cmpl   $0x24,-0x44(%rbp)
  jle    L243
L409:
  mov    D24(%rip),%rax
  mov    (%rax),%edx
  mov    D52(%rip),%rax
  mov    %edx,(%rax)
  cmpq   $0x0,-0x40(%rbp)
  je     L117
  mov    -0x40(%rbp),%rax
  mov    -0x38(%rbp),%rdx
  mov    %rdx,(%rax)
L117:
  mov    $0x0,%eax
  jmp    L335
L243:
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x18(%rbp)
L123:
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x29(%rbp)
  movzbl -0x29(%rbp),%eax
  mov    %eax,%edi
  call   <isspace@plt>
  test   %rax,%rax
  jne    L123
  cmpb   $0x2d,-0x29(%rbp)
  jne    L65
  movl   $0x1,-0x24(%rbp)
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x29(%rbp)
  jmp    L22
L65:
  movl   $0x0,-0x24(%rbp)
  cmpb   $0x2b,-0x29(%rbp)
  jne    L22
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x29(%rbp)
L22:
  cmpl   $0x0,-0x44(%rbp)
  je     L50
  cmpl   $0x10,-0x44(%rbp)
  jne    L420
L50:
  cmpb   $0x30,-0x29(%rbp)
  jne    L420
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x78,%al
  je     L0
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x58,%al
  jne    L420
L0:
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jle    L336
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x39,%al
  jle    L110
L336:
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x60,%al
  jle    L97
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x66,%al
  jle    L110
L97:
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x40,%al
  jle    L420
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x46,%al
  jg     L420
L110:
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  mov    %al,-0x29(%rbp)
  addq   $0x2,-0x18(%rbp)
  movl   $0x10,-0x44(%rbp)
  jmp    L392
L420:
  cmpl   $0x0,-0x44(%rbp)
  jne    L392
  cmpb   $0x30,-0x29(%rbp)
  jne    L236
  mov    $0x8,%eax
  jmp    L152
L236:
  mov    $0xa,%eax
L152:
  mov    %eax,-0x44(%rbp)
L392:
  mov    D68(%rip),%rax
  mov    (%rax),%rax
  mov    -0x44(%rbp),%edx
  movslq %edx,%rsi
  mov    $0x0,%edx
  div    %rsi
  mov    %rax,-0x8(%rbp)
  mov    D68(%rip),%rax
  mov    (%rax),%rax
  mov    -0x44(%rbp),%edx
  movslq %edx,%rcx
  mov    $0x0,%edx
  div    %rcx
  mov    %rdx,%rax
  mov    %eax,-0x1c(%rbp)
  movq   $0x0,-0x10(%rbp)
  movl   $0x0,-0x20(%rbp)
L406:
  cmpb   $0x2f,-0x29(%rbp)
  jbe    L297
  cmpb   $0x39,-0x29(%rbp)
  ja     L297
  movzbl -0x29(%rbp),%eax
  sub    $0x30,%eax
  mov    %eax,-0x28(%rbp)
  jmp    L303
L297:
  cmpb   $0x60,-0x29(%rbp)
  jbe    L33
  cmpb   $0x7a,-0x29(%rbp)
  ja     L33
  movzbl -0x29(%rbp),%eax
  sub    $0x57,%eax
  mov    %eax,-0x28(%rbp)
  jmp    L303
L33:
  cmpb   $0x40,-0x29(%rbp)
  jbe    L39
  cmpb   $0x5a,-0x29(%rbp)
  ja     L39
  movzbl -0x29(%rbp),%eax
  sub    $0x37,%eax
  mov    %eax,-0x28(%rbp)
L303:
  mov    -0x28(%rbp),%eax
  cmp    -0x44(%rbp),%eax
  jge    L107
  cmpl   $0x0,-0x20(%rbp)
  js     L262
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  ja     L394
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jne    L314
  mov    -0x28(%rbp),%eax
  cmp    -0x1c(%rbp),%eax
  jle    L314
L394:
  mov    D68(%rip),%rax
  mov    (%rax),%rax
  mov    %rax,-0x10(%rbp)
  movl   $0xffffffff,-0x20(%rbp)
  mov    D61(%rip),%rax
  mov    (%rax),%edx
  mov    D52(%rip),%rax
  mov    %edx,(%rax)
  jmp    L209
L314:
  movl   $0x1,-0x20(%rbp)
  mov    -0x44(%rbp),%eax
  cltq
  mov    -0x10(%rbp),%rdx
  imul   %rdx,%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x28(%rbp),%eax
  cltq
  add    %rax,-0x10(%rbp)
  jmp    L209
L262:
  nop
L209:
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x29(%rbp)
  jmp    L406
L107:
  nop
L39:
  cmpl   $0x0,-0x24(%rbp)
  je     L277
  cmpl   $0x0,-0x20(%rbp)
  jle    L277
  negq   -0x10(%rbp)
L277:
  cmpq   $0x0,-0x40(%rbp)
  je     L282
  cmpl   $0x0,-0x20(%rbp)
  je     L17
  mov    -0x18(%rbp),%rax
  sub    $0x1,%rax
  jmp    L436
L17:
  mov    -0x38(%rbp),%rax
L436:
  mov    -0x40(%rbp),%rdx
  mov    %rax,(%rdx)
L282:
  mov    -0x10(%rbp),%rax
L335:
  leave
  ret
```

assistant: ```c
unsigned long int strtoul(const char *nptr, char **endptr, int base) {
  const char *s;
  unsigned long int acc, cutoff;
  unsigned char c;
  int i, neg, any, cutlim;
  assert(nptr != NULL);
  if (base && (base < 2 || base > 36)) {
    errno = EINVAL;
    if (endptr != NULL)
      *endptr = (char *)(nptr);
    return 0;
  }
  s = nptr;
  do {
    c = *s++;
  } while (isspace(c));
  if (c == '-') {
    neg = 1;
    c = *s++;
  } else {
    neg = 0;
    if (c == '+')
      c = *s++;
  }
  if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'a' && s[1] <= 'f') || (s[1] >= 'A' && s[1] <= 'F'))) {
    c = s[1];
    s += 2;
    base = 16;
  } else if (base == 0)
    base = (c == '0' ? 8 : 10);
  cutoff = ((unsigned long int)ULONG_MAX / (unsigned long int)base);
  cutlim = (int)((unsigned long int)ULONG_MAX % (unsigned long int)base);
  for (acc = 0, any = 0;; c = *s++) {
    if (c >= '0' && c <= '9')
      i = c - '0';
    else if (c >= 'a' && c <= 'z')
      i = (c - 'a') + 10;
    else if (c >= 'A' && c <= 'Z')
      i = (c - 'A') + 10;
    else
      break;
    if (i >= base)
      break;
    if (any < 0)
      continue;
    if (acc > cutoff || (acc == cutoff && i > cutlim)) {
      acc = ULONG_MAX;
      any = -1;
      errno = ERANGE;
    } else {
      any = 1;
      acc *= (unsigned long int)base;
      acc += i;
    }
  }
  if (neg && any > 0)
    acc = -acc;
  if (endptr != NULL)
    *endptr = (char *)(any ? s - 1 : nptr);
  return (acc);
}
```