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

```asm
<strtol>:
  endbr64
  push   %r12
  mov    %edx,%r9d
  mov    %rdi,%rcx
  push   %rbp
  mov    %rsi,%rbp
  push   %rbx
  mov    %rdi,%rbx
L78:
  movzbl (%rcx),%eax
  cmp    $0xd,%al
  jg     L24
  cmp    $0x8,%al
  jg     L111
L126:
  lea    -0x2b(%rax),%edx
  xor    %r12d,%r12d
  and    $0xfd,%edx
  jne    L109
  xor    %r12d,%r12d
  add    $0x1,%rcx
  cmp    $0x2d,%al
  sete   %r12b
L109:
  test   %r9d,%r9d
  jne    L169
  movsbl (%rcx),%edx
  mov    $0xa,%r9d
  cmp    $0x30,%dl
  je     L226
L15:
  xor    %edi,%edi
  xor    %esi,%esi
  xor    %r8d,%r8d
  movslq %r9d,%r11
  mov    $0x1,%r10d
  jmp    L152
  nop
L11:
  lea    -0x57(%rdx),%eax
L122:
  cmp    %r9d,%eax
  jge    L71
  mov    %r11,%rdx
  cltq
  imul   %r8,%rdx
  add    %rdx,%rax
  cmp    %rax,%r8
  mov    %rax,%r8
  cmovg  %r10d,%esi
  movsbl 0x1(%rcx),%edx
  add    $0x1,%rcx
  add    $0x1,%edi
L152:
  lea    -0x30(%rdx),%eax
  cmp    $0x9,%eax
  jbe    L122
  lea    -0x61(%rdx),%eax
  cmp    $0x19,%eax
  jbe    L11
  lea    -0x41(%rdx),%eax
  cmp    $0x19,%eax
  jbe    L241
L71:
  test   %edi,%edi
  cmove  %rbx,%rcx
  test   %rbp,%rbp
  je     L232
  mov    %rcx,0x0(%rbp)
L232:
  test   %esi,%esi
  je     L203
  mov    D17(%rip),%rax
  mov    (%rax),%edx
  mov    D34(%rip),%rax
  mov    %edx,(%rax)
  test   %r12d,%r12d
  je     L139
  mov    D20(%rip),%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  mov    (%rax),%r8
  mov    %r8,%rax
  ret
  nopl   (%rax)
L24:
  cmp    $0x20,%al
  jne    L126
L111:
  add    $0x1,%rcx
  jmp    L78
  nopl   0x0(%rax)
L241:
  lea    -0x37(%rdx),%eax
  jmp    L122
L169:
  cmp    $0x10,%r9d
  je     L38
  cmp    $0x24,%r9d
  jbe    L50
  xor    %r8d,%r8d
  test   %rbp,%rbp
  je     L203
  mov    %rbx,0x0(%rbp)
L203:
  mov    %r8,%rax
  pop    %rbx
  pop    %rbp
  neg    %rax
  test   %r12d,%r12d
  pop    %r12
  cmovne %rax,%r8
  mov    %r8,%rax
  ret
  nopl   (%rax)
L139:
  mov    D23(%rip),%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  mov    (%rax),%r8
  mov    %r8,%rax
  ret
  nopw   0x0(%rax,%rax,1)
L50:
  movsbl (%rcx),%edx
  jmp    L15
L226:
  movzbl 0x1(%rcx),%eax
  mov    $0x8,%r9d
  and    $0xffffffdf,%eax
  cmp    $0x58,%al
  jne    L15
  movsbl 0x2(%rcx),%edx
  mov    $0x10,%r9d
  add    $0x2,%rcx
  jmp    L15
  nopl   0x0(%rax,%rax,1)
L38:
  movsbl (%rcx),%edx
  cmp    $0x30,%dl
  jne    L15
  movzbl 0x1(%rcx),%eax
  and    $0xffffffdf,%eax
  cmp    $0x58,%al
  jne    L15
  movsbl 0x2(%rcx),%edx
  add    $0x2,%rcx
  jmp    L15
```

assistant: ```c
long strtol(const char *nptr, char **endptr, int base) {
  const char *p;
  long n, nn;
  int c, ovfl, v, neg, ndig;
  p = nptr;
  neg = 0;
  n = 0;
  ndig = 0;
  ovfl = 0;
  for (;; p++) {
    switch (*p) {
    case ' ':
    case '\t':
    case '\n':
    case '\f':
    case '\r':
    case '\v':
      continue;
    }
    break;
  }
  if (*p == '-' || *p == '+')
    if (*p++ == '-')
      neg = 1;
  if (base == 0) {
    if (*p != '0')
      base = 10;
    else {
      base = 8;
      if (p[1] == 'x' || p[1] == 'X') {
        p += 2;
        base = 16;
      }
    }
  } else if (base == 16 && *p == '0') {
    if (p[1] == 'x' || p[1] == 'X')
      p += 2;
  } else if (base < 0 || 36 < base)
    goto Return;
  for (;; p++, ndig++) {
    c = *p;
    v = base;
    if ('0' <= c && c <= '9')
      v = c - '0';
    else if ('a' <= c && c <= 'z')
      v = c - 'a' + 10;
    else if ('A' <= c && c <= 'Z')
      v = c - 'A' + 10;
    if (v >= base)
      break;
    nn = n * base + v;
    if (nn < n)
      ovfl = 1;
    n = nn;
  }
Return:
  if (ndig == 0)
    p = nptr;
  if (endptr)
    *endptr = (char *)p;
  if (ovfl) {
    errno = ERANGE;
    if (neg)
      return LONG_MIN;
    return LONG_MAX;
  }
  if (neg)
    return -n;
  return n;
}
```