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

```asm
<strtol>:
  endbr64
  push   %r15
  mov    %rdi,%r15
  push   %r14
  push   %r13
  push   %r12
  mov    %edx,%r12d
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rsi,(%rsp)
  jmp    L65
  xchg   %ax,%ax
L19:
  add    $0x1,%r15
L65:
  movsbl (%r15),%edi
  call   <isspace@plt>
  mov    %rax,%r14
  test   %rax,%rax
  jne    L19
  movsbl (%r15),%edi
  cmp    $0x2d,%dil
  je     L81
  movb   $0x0,0xf(%rsp)
  cmp    $0x2b,%dil
  je     L165
L162:
  test   %r12d,%r12d
  jne    L152
L219:
  mov    $0xa,%ebx
  cmp    $0x30,%dil
  je     L257
L142:
  movslq %ebx,%rbp
  jmp    L254
  nop
L245:
  sub    $0x37,%eax
L29:
  cmp    %bl,%al
  jge    L158
  mov    %rbp,%rcx
  movsbq %al,%rax
  imul   %r14,%rcx
  add    %rcx,%rax
  cmp    %rax,%r14
  jg     L227
  movsbl 0x0(%r13),%edi
  mov    %r13,%r15
  mov    %rax,%r14
L254:
  lea    0x1(%r15),%r13
  call   <toupper@plt>
  cmp    $0x40,%al
  jg     L245
  sub    $0x30,%al
  jns    L29
L158:
  cmpq   $0x0,(%rsp)
  je     L166
  test   %r12d,%r12d
  je     L15
  cs nopw 0x0(%rax,%rax,1)
L64:
  mov    (%rsp),%rax
  mov    %r15,(%rax)
L166:
  mov    %r14,%rax
  neg    %rax
  cmpb   $0x0,0xf(%rsp)
  cmovne %rax,%r14
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  mov    %r14,%rax
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L15:
  movzbl (%r15),%eax
  sub    $0x4c,%eax
  cmp    $0x29,%al
  ja     L64
  movabs $0xfffffdfeeffffffe,%rcx
  bt     %rax,%rcx
  jb     L64
  movzbl 0x0(%r13),%eax
  mov    %r13,%r15
  sub    $0x4c,%eax
  cmp    $0x29,%al
  ja     L64
L236:
  bt     %rax,%rcx
  jb     L64
  movzbl 0x1(%r13),%eax
  add    $0x1,%r13
  mov    %r13,%r15
  sub    $0x4c,%eax
  cmp    $0x29,%al
  ja     L64
  jmp    L236
  nopl   (%rax)
L165:
  movsbl 0x1(%r15),%edi
  add    $0x1,%r15
  test   %r12d,%r12d
  je     L219
L152:
  mov    %r12d,%ebx
  cmp    $0x10,%r12d
  jne    L142
  cmp    $0x30,%dil
  jne    L142
  movzbl 0x1(%r15),%eax
  and    $0xffffffdf,%eax
  cmp    $0x58,%al
  jne    L142
  movsbl 0x2(%r15),%edi
  add    $0x2,%r15
  jmp    L142
  nop
L81:
  movsbl 0x1(%r15),%edi
  movb   $0x1,0xf(%rsp)
  add    $0x1,%r15
  jmp    L162
  nopl   0x0(%rax,%rax,1)
L227:
  cmpb   $0x0,0xf(%rsp)
  jne    L256
  mov    D21(%rip),%rax
  mov    (%rax),%r14
L129:
  mov    D26(%rip),%rax
  mov    (%rax),%ecx
  mov    D29(%rip),%rax
  mov    %ecx,(%rax)
  jmp    L158
L257:
  movzbl 0x1(%r15),%eax
  xor    %ebx,%ebx
  and    $0xffffffdf,%eax
  cmp    $0x58,%al
  sete   %bl
  lea    0x8(,%rbx,8),%ebx
  jmp    L142
  nopl   0x0(%rax,%rax,1)
L256:
  mov    D8(%rip),%rax
  mov    (%rax),%r14
  jmp    L129
```

assistant: ```c
long strtol(const char *__restrict nptr, char **__restrict endptr, int base) {
  long sum, psum;
  char sign;
  int radix = base;
  char *cp = (char *)nptr;
  char digit;
  while (isspace(*cp))
    ++cp;
  sign = 0;
  if (*cp == (char)'-') {
    sign = 1;
    ++cp;
  } else if (*cp == (char)'+')
    ++cp;
  if (base == 0) {
    radix = 10;
    if (*cp == (char)'0') {
      if (cp[1] == (char)'x' || cp[1] == (char)'X') {
        radix = 16;
      } else {
        radix = 8;
      }
    }
  }
  if (base == 16 && *cp == (char)'0' && (cp[1] == (char)'x' || cp[1] == (char)'X'))
    cp += 2;
  sum = 0;
  for (;;) {
    digit = toupper(*(cp++));
    if (digit >= (char)'A')
      digit = (digit - (char)'A') + (char)10;
    else
      digit -= (char)'0';
    if (digit < (char)0 || digit >= (char)radix)
      break;
    psum = sum;
    sum *= radix;
    sum += digit;
    if (sum < psum) {
      sum = sign ? LONG_MIN : LONG_MAX;
      errno = ERANGE;
      break;
    }
  }
  if (endptr) {
    --cp;
    if (base == 0) {
      while (*cp == (char)'h' || *cp == (char)'u' || *cp == (char)'l' || *cp == (char)'L')
        ++cp;
    }
    *endptr = (char *)cp;
  }
  return (sign ? -sum : sum);
}
```