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

```asm
<end_ip>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x20,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jb     L81
  mov    $0x0,%eax
  jmp    L10
L81:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L48
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L143
L48:
  mov    $0x0,%eax
  jmp    L10
L143:
  addq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L20
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L20
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L20
  addq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L20
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L20
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L20
  addq   $0x1,-0x18(%rbp)
L20:
  movl   $0x0,-0x4(%rbp)
  jmp    L126
L89:
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L49
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  je     L67
L49:
  mov    $0x0,%eax
  jmp    L10
L67:
  addq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L149
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L149
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  jne    L297
L149:
  mov    $0x0,%eax
  jmp    L10
L297:
  addq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L271
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L271
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L271
  addq   $0x1,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L271
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L271
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L271
  addq   $0x1,-0x18(%rbp)
L271:
  addl   $0x1,-0x4(%rbp)
L126:
  cmpl   $0x2,-0x4(%rbp)
  jle    L89
  mov    -0x18(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  jae    L75
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L75
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L75
  mov    $0x0,%eax
  jmp    L10
L75:
  mov    -0x18(%rbp),%rax
L10:
  leave
  ret
```

assistant: ```c
char const *end_ip(char const *s, char const *e) {
  int i;
  if (s >= e)
    return NULL;
  if (!(isascii(*s) && isdigit(*s)))
    return NULL;
  s++;
  if (s < e && (isascii(*s) && isdigit(*s))) {
    s++;
    if (s < e && (isascii(*s) && isdigit(*s)))
      s++;
  }
  for (i = 0; i < 3; i++) {
    if (s >= e || *s != '.')
      return NULL;
    s++;
    if (s >= e || !(isascii(*s) && isdigit(*s)))
      return NULL;
    s++;
    if (s < e && (isascii(*s) && isdigit(*s))) {
      s++;
      if (s < e && (isascii(*s) && isdigit(*s)))
        s++;
    }
  }
  if (s < e && (isascii(*s) && isdigit(*s)))
    return NULL;
  return s;
}
```