user: Translate the below assembly code into C programming language:

```asm
<end_ip>:
  endbr64
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  mov    $0x0,%ebp
  cmp    %rsi,%rdi
  jae    L305
  mov    %rdi,%r12
  mov    %rsi,%rbx
  movsbl (%rdi),%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L305
  movsbl (%r12),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L116
  lea    0x1(%r12),%r13
  cmp    %r13,%rbx
  ja     L221
L63:
  mov    $0x0,%ebp
  jmp    L305
L221:
  movsbl 0x1(%r12),%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L82
  movsbl 0x1(%r12),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L82
  lea    0x2(%r12),%r13
  cmp    %r13,%rbx
  jbe    L63
  movsbl 0x2(%r12),%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L82
  movsbl 0x2(%r12),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L82
  lea    0x3(%r12),%r13
  cmp    %r13,%rbx
  jbe    L17
L82:
  mov    $0x3,%r12d
  jmp    L122
L315:
  movsbl 0x3(%r13),%edi
  call   <isascii@plt>
  test   %rax,%rax
  jne    L50
L266:
  sub    $0x1,%r12d
  jne    L265
  jmp    L303
L50:
  movsbl 0x3(%r13),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L266
  lea    0x4(%r13),%rbp
L59:
  sub    $0x1,%r12d
  je     L303
  cmp    %rbx,%rbp
  jae    L179
L265:
  mov    %rbp,%r13
L122:
  cmpb   $0x2e,0x0(%r13)
  jne    L20
  lea    0x1(%r13),%rax
  cmp    %rax,%rbx
  jbe    L376
  movsbl 0x1(%r13),%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L279
  movsbl 0x1(%r13),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L127
  lea    0x2(%r13),%rbp
  cmp    %rbp,%rbx
  jbe    L59
  movsbl 0x2(%r13),%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L59
  movsbl 0x2(%r13),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  je     L266
  lea    0x3(%r13),%rbp
  cmp    %rbp,%rbx
  ja     L315
  cmp    $0x1,%r12d
  jne    L361
L303:
  cmp    %rbp,%rbx
  ja     L248
L305:
  mov    %rbp,%rax
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
L248:
  movsbl 0x0(%rbp),%edi
  call   <isascii@plt>
  test   %rax,%rax
  je     L305
  movsbl 0x0(%rbp),%edi
  call   <isdigit@plt>
  test   %rax,%rax
  mov    $0x0,%eax
  cmovne %rax,%rbp
  jmp    L305
L116:
  mov    $0x0,%ebp
  jmp    L305
L17:
  mov    $0x0,%ebp
  jmp    L305
L179:
  mov    $0x0,%ebp
  jmp    L305
L20:
  mov    $0x0,%ebp
  jmp    L305
L376:
  mov    $0x0,%ebp
  jmp    L305
L279:
  mov    $0x0,%ebp
  jmp    L305
L127:
  mov    $0x0,%ebp
  jmp    L305
L361:
  mov    $0x0,%ebp
  jmp    L305
```

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;
}
```