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

```asm
<strtol>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rsi,0x18(%rsp)
  test   %rdi,%rdi
  je     L110
  mov    $0x10,%ebx
  mov    %rdi,%r15
  mov    %edx,%ebp
  cmp    %ebx,%edx
  cmovle %edx,%ebx
  jmp    L222
  nopl   0x0(%rax)
L28:
  add    $0x1,%r15
L222:
  movsbl (%r15),%edi
  call   <isspace@plt>
  mov    %rax,%r13
  test   %rax,%rax
  jne    L28
  movzbl (%r15),%ecx
  cmp    $0x2d,%cl
  je     L63
  movl   $0x0,0x14(%rsp)
  cmp    $0x2b,%cl
  je     L365
L359:
  mov    %ebp,%eax
  and    $0xfffffffd,%eax
  cmp    $0xf,%ebp
  jg     L235
  test   %ebp,%ebp
  je     L235
  test   %eax,%eax
  jne    L173
  cmp    $0x30,%cl
  je     L217
L227:
  test   %ebp,%ebp
  jne    L173
  mov    0x14(%rsp),%edi
  mov    $0xa,%esi
  mov    $0xa,%ebx
  test   %edi,%edi
  je     L123
L75:
  mov    $0xffffffff80000000,%rax
  xor    %edx,%edx
  div    %rsi
  mov    %rdx,0x8(%rsp)
  mov    %rax,%rbp
  jmp    L147
  nopw   0x0(%rax,%rax,1)
L235:
  cmp    $0x30,%cl
  je     L324
  test   %eax,%eax
  je     L227
L173:
  movslq %ebx,%rsi
L52:
  mov    0x14(%rsp),%edi
  test   %edi,%edi
  jne    L75
L123:
  mov    $0x7fffffff,%eax
  xor    %edx,%edx
  div    %rsi
  mov    %rdx,0x8(%rsp)
  mov    %rax,%rbp
L147:
  test   %cl,%cl
  je     L269
L277:
  movslq %ebx,%r12
  jmp    L73
  nopl   0x0(%rax,%rax,1)
L346:
  cmp    %ebx,%edx
  jge    L269
L280:
  cmp    %rbp,%r13
  ja     L269
  movslq %edx,%rdx
  je     L181
L233:
  mov    %r13,%r9
  movzbl 0x1(%r15),%ecx
  add    $0x1,%r15
  imul   %r12,%r9
  lea    (%r9,%rdx,1),%r13
  test   %cl,%cl
  je     L269
L73:
  movsbl %cl,%r14d
  mov    %r14d,%edi
  call   <isdigit@plt>
  lea    -0x30(%r14),%edx
  test   %rax,%rax
  jne    L346
  mov    %r14d,%edi
  call   <isalpha@plt>
  test   %rax,%rax
  je     L269
  mov    %r14d,%edi
  call   <isupper@plt>
  lea    -0x57(%r14),%edx
  mov    %rax,%r10
  lea    -0x37(%r14),%eax
  test   %r10,%r10
  cmovne %eax,%edx
  cmp    %ebx,%edx
  jl     L280
  nopl   0x0(%rax)
L269:
  mov    0x18(%rsp),%rax
  test   %rax,%rax
  je     L153
  mov    %r15,(%rax)
L153:
  mov    0x14(%rsp),%edx
  mov    %r13,%rax
  neg    %rax
  test   %edx,%edx
  cmovne %rax,%r13
L162:
  add    $0x28,%rsp
  mov    %r13,%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nop
L181:
  cmp    %rdx,0x8(%rsp)
  jge    L233
  jmp    L269
  nopl   (%rax)
L63:
  movzbl 0x1(%r15),%ecx
  movl   $0x1,0x14(%rsp)
  add    $0x1,%r15
  jmp    L359
  cs nopw 0x0(%rax,%rax,1)
L365:
  movzbl 0x1(%r15),%ecx
  add    $0x1,%r15
  jmp    L359
L217:
  movzbl 0x1(%r15),%edx
  and    $0xffffffdf,%edx
L219:
  cmp    $0x42,%dl
  jne    L339
  movzbl 0x2(%r15),%ecx
  mov    $0x2,%esi
  add    $0x2,%r15
  mov    $0x2,%ebx
  jmp    L52
  nopl   0x0(%rax,%rax,1)
L110:
  xor    %r13d,%r13d
  jmp    L162
L324:
  movzbl 0x1(%r15),%edx
  and    $0xffffffdf,%edx
  cmp    $0x58,%dl
  jne    L286
  movzbl 0x2(%r15),%ecx
  mov    $0x10,%esi
  add    $0x2,%r15
  mov    $0x10,%ebx
  jmp    L52
L339:
  test   %ebp,%ebp
  jne    L173
  mov    0x14(%rsp),%eax
  mov    $0xfffffff,%ebp
  mov    $0x8,%ebx
  cmp    $0x1,%eax
  sbb    %rsi,%rsi
  and    $0x7,%esi
  test   %eax,%eax
  movabs $0x1ffffffff0000000,%rax
  mov    %rsi,0x8(%rsp)
  cmovne %rax,%rbp
  jmp    L277
L286:
  test   %eax,%eax
  jne    L173
  jmp    L219
```

assistant: ```c
long int strtol(const char *str, char **endptr, int base) {
  long int value = 0;
  int neg = 0;
  if (str == NULL)
    return (0);
  if (base >= 16)
    base = 16;
  while (isspace(*str))
    str++;
  if (*str == '-') {
    neg = 1;
    str++;
  } else if (*str == '+')
    str++;
  if ((base == 16 || base == 0) && *str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) {
    str += 2;
    base = 16;
  } else if ((base == 0 || base == 2) && *str == '0' && (*(str + 1) == 'b' || *(str + 1) == 'B')) {
    str += 2;
    base = 2;
  }
  if (base == 0) {
    if (*str == '0') {
      base = 8;
    } else
      base = 10;
  }
  unsigned long cutoff_value = 0;
  if (neg)
    cutoff_value = -(unsigned long)(0x80000000L);
  else
    cutoff_value = (unsigned long)(0x7FFFFFFFL);
  long int cutlim_value = cutoff_value % (unsigned long)base;
  cutoff_value /= base;
  while (*str != '\0') {
    int c = *str;
    if (isdigit(c))
      c -= '0';
    else if (isalpha(c)) {
      if (isupper(c))
        c -= ('A' - 10);
      else
        c -= ('a' - 10);
    } else
      break;
    if (c >= base)
      break;
    if (value > cutoff_value || (value == cutoff_value && c > cutlim_value))
      break;
    else {
      value *= base;
      value += c;
    }
    str++;
  }
  if (endptr)
    *endptr = (char *)str;
  if (neg)
    return -value;
  else
    return value;
}
```