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

```asm
<get_long>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  mov    %rdi,%r12
  push   %rbp
  mov    %rsi,%rbp
  push   %rbx
  sub    $0x18,%rsp
  movl   $0x0,(%rsi)
  movsbl (%rdi),%edi
  cmp    $0x2d,%dil
  je     L375
  xor    %r13d,%r13d
  cmp    $0x2b,%dil
  je     L53
L77:
  call   <isdigit@plt>
  test   %rax,%rax
  je     L255
  mov    %r12,%rbx
  nopl   (%rax)
L348:
  movsbl 0x1(%rbx),%edi
  add    $0x1,%rbx
  call   <isxdigit@plt>
  test   %rax,%rax
  jne    L348
  movsbl (%rbx),%edi
  call   <upcase@plt>
  cmp    $0x48,%al
  je     L136
L255:
  movzbl (%r12),%eax
  cmp    $0x23,%al
  je     L440
L480:
  cmp    $0x30,%al
  je     L266
L477:
  mov    $0x3,%edx
  lea    D7(%rip),%rsi
  mov    %r12,%rdi
  call   <strncmp@plt>
  test   %rax,%rax
  jne    L214
  movb   $0x1,0xf(%rsp)
  add    $0x3,%r12
  xor    %r14d,%r14d
  nopl   0x0(%rax,%rax,1)
L5:
  mov    %r12,%r15
  jmp    L96
  nopl   (%rax)
L88:
  mov    0x0(%rbp),%ebx
  movsbl (%r15),%edi
  add    $0x1,%r15
  call   <xtoi@plt>
  shl    $0x4,%ebx
  or     %eax,%ebx
  mov    %ebx,0x0(%rbp)
L96:
  movsbl (%r15),%edi
  call   <isxdigit@plt>
  test   %rax,%rax
  jne    L88
  mov    %r15,%rax
  sub    %r12,%rax
  cmp    $0x8,%rax
  jg     L106
  test   %r14b,%r14b
  jne    L422
  cmpb   $0x0,0xf(%rsp)
  je     L107
  cmpb   $0x23,(%r15)
  jne    L159
L422:
  add    $0x1,%r15
L107:
  test   %r13b,%r13b
  je     L261
  negl   0x0(%rbp)
L261:
  add    $0x18,%rsp
  mov    %r15,%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L53:
  movsbl 0x1(%r12),%edi
  add    $0x1,%r12
  jmp    L77
  nopw   0x0(%rax,%rax,1)
L375:
  movsbl 0x1(%r12),%edi
  mov    $0x1,%r13d
  add    $0x1,%r12
  jmp    L77
  nopl   (%rax)
L214:
  movzbl (%r12),%eax
  cmp    $0x30,%al
  je     L209
  cmp    $0x38,%al
  je     L125
  cmp    $0x40,%al
  jne    L86
  movzbl 0x1(%r12),%eax
  lea    0x1(%r12),%rsi
  xor    %edi,%edi
  lea    -0x30(%rax),%edx
  cmp    $0x1,%dl
  ja     L81
L350:
  mov    0x0(%rbp),%edx
  mov    %rsi,%r15
  nopl   0x0(%rax)
L94:
  sub    $0x30,%eax
  add    %edx,%edx
  add    $0x1,%r15
  movsbl %al,%eax
  or     %eax,%edx
  mov    %edx,0x0(%rbp)
  movzbl (%r15),%eax
  lea    -0x30(%rax),%ecx
  cmp    $0x1,%cl
  jbe    L94
  mov    %r15,%rdx
  sub    %rsi,%rdx
  cmp    $0x20,%rdx
  jle    L441
  jmp    L123
  nopw   0x0(%rax,%rax,1)
L136:
  movb   $0x0,0xf(%rsp)
  mov    $0x1,%r14d
  jmp    L5
L266:
  movsbl 0x1(%r12),%edi
  call   <upcase@plt>
  cmp    $0x58,%al
  jne    L477
  movb   $0x0,0xf(%rsp)
  add    $0x2,%r12
  xor    %r14d,%r14d
  jmp    L5
  nopl   0x0(%rax)
L440:
  movsbl 0x1(%r12),%edi
  call   <isxdigit@plt>
  test   %rax,%rax
  jne    L196
  movzbl (%r12),%eax
  jmp    L480
L125:
  cmpb   $0x23,0x1(%r12)
  je     L204
L104:
  movsbl %al,%edi
  mov    %r12,%r15
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L322
  jmp    L215
L170:
  mov    0x0(%rbp),%eax
  add    $0x1,%r15
  lea    (%rax,%rax,4),%edx
  movsbl -0x1(%r15),%eax
  lea    -0x30(%rax,%rdx,2),%eax
  mov    %eax,0x0(%rbp)
L322:
  movsbl (%r15),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L170
  mov    %r15,%rax
  sub    %r12,%rax
  cmp    $0xa,%rax
  jle    L107
  nopl   0x0(%rax)
L106:
  mov    %r12,%rsi
L123:
  lea    D15(%rip),%rdi
  xor    %eax,%eax
  call   <error@plt>
L215:
  xor    %r15d,%r15d
  jmp    L261
L196:
  movb   $0x0,0xf(%rsp)
  add    $0x1,%r12
  xor    %r14d,%r14d
  jmp    L5
L209:
  movzbl 0x1(%r12),%eax
  lea    0x1(%r12),%rsi
  xor    %edi,%edi
  lea    -0x30(%rax),%edx
  cmp    $0x7,%dl
  ja     L81
L251:
  mov    0x0(%rbp),%edx
  mov    %rsi,%r15
  nopl   0x0(%rax)
L369:
  sub    $0x30,%eax
  shl    $0x3,%edx
  add    $0x1,%r15
  movsbl %al,%eax
  or     %eax,%edx
  mov    %edx,0x0(%rbp)
  movzbl (%r15),%eax
  lea    -0x30(%rax),%ecx
  cmp    $0x7,%cl
  jbe    L369
  mov    %r15,%rdx
  sub    %rsi,%rdx
  cmp    $0xb,%rdx
  jg     L123
L441:
  test   %dil,%dil
  je     L107
L446:
  cmp    $0x23,%al
  je     L422
L159:
  lea    D6(%rip),%rdi
  xor    %eax,%eax
  xor    %r15d,%r15d
  call   <error@plt>
  jmp    L261
L204:
  movzbl 0x2(%r12),%eax
  lea    0x2(%r12),%rsi
  mov    $0x1,%edi
  lea    -0x30(%rax),%edx
  cmp    $0x7,%dl
  jbe    L251
L14:
  mov    %rsi,%r15
  jmp    L446
L86:
  cmp    $0x32,%al
  jne    L104
  cmpb   $0x23,0x1(%r12)
  jne    L104
  movzbl 0x2(%r12),%eax
  lea    0x2(%r12),%rsi
  mov    $0x1,%edi
  lea    -0x30(%rax),%edx
  cmp    $0x1,%dl
  jbe    L350
  jmp    L14
  nopl   0x0(%rax,%rax,1)
L81:
  mov    %rsi,%r15
  jmp    L107
```

tool_calls: name: read_data
arguments: data_label: D7
data_type: string
name: read_data
arguments: data_label: D15
data_type: string
name: read_data
arguments: data_label: D6
data_type: string

tool: D7: 16#

tool: D15: get_long -- number at '%s' too large

tool: D6: get_long -- expecting '#' at end of number

assistant: ```c
char *get_long(char *s, int *outnum) {
  char is_neg = 0, intel = 0, c_lang = 0, tld = 0;
  char hash_hex = 0;
  char *start;
  *outnum = 0;
  if (*s == '-') {
    is_neg = (!0);
    ++s;
  } else if (*s == '+')
    ++s;
  if (isdigit(*s)) {
    char *p = s;
    while (isxdigit(*++p))
      ;
    if (upcase(*p) == 'H')
      intel = (!0);
  }
  if (intel || (hash_hex = (*s == '#' && isxdigit(*(s + 1)))) || (c_lang = (*s == '0' && upcase(*(s + 1)) == 'X')) || (tld = strncmp(s, "16#", 3) == 0)) {
    s += hash_hex ? 1 : c_lang ? 2 : tld ? 3 : 0;
    start = s;
    while (isxdigit(*s)) {
      *outnum = (*outnum << 4) | xtoi(*s);
      ++s;
    }
    if (s - start > 8) {
      error("get_long -- number at '%s' too large", start);
      return NULL;
    }
    if (intel)
      s++;
    else if (tld) {
      if (*s != '#') {
        error("get_long -- expecting '#' at end of number");
        return NULL;
      }
      s++;
    }
  } else if (*s == '0' || (tld = (*s == '8' && *(s + 1) == '#'))) {
    s += tld ? 2 : 1;
    start = s;
    while (*s >= '0' && *s <= '7') {
      *outnum = (*outnum << 3) | (*s - '0');
      ++s;
    }
    if (s - start > 11) {
      error("get_long -- number at '%s' too large", start);
      return NULL;
    }
    if (tld) {
      if (*s != '#') {
        error("get_long -- expecting '#' at end of number");
        return NULL;
      }
      ++s;
    }
  } else if (*s == '@' || (tld = (*s == '2' && *(s + 1) == '#'))) {
    s += (tld ? 2 : 1);
    start = s;
    while (*s == '0' || *s == '1') {
      *outnum = (*outnum << 1) | (*s - '0');
      ++s;
    }
    if (s - start > 32) {
      error("get_long -- number at '%s' too large", start);
      return NULL;
    }
    if (tld) {
      if (*s != '#') {
        error("get_long -- expecting '#' at end of number");
        return NULL;
      }
      ++s;
    }
  } else if (isdigit(*s)) {
    start = s;
    while (isdigit(*s)) {
      *outnum = (*outnum * 10) + ((*s) - '0');
      ++s;
    }
    if (s - start > 10) {
      error("get_long -- number at '%s' too large", start);
      return NULL;
    }
  } else
    return NULL;
  if (is_neg)
    *outnum = -*outnum;
  return s;
}
```