user: 请显示与下面列出的汇编代码相匹配的C语言实现:

```asm
<fast_validate_len>:
  endbr64
  push   %rbp
  mov    %rsi,%rbp
  push   %rbx
  mov    %rdi,%rbx
  mov    $0x1,%edi
  sub    $0x8,%rsp
  call   <assert@plt>
  mov    %rbx,%rax
  test   %rbp,%rbp
  je     L78
  xor    %ecx,%ecx
  jmp    L5
  nopw   0x0(%rax,%rax,1)
L73:
  add    $0x1,%rax
  mov    %rax,%rcx
  sub    %rbx,%rcx
  cmp    %rbp,%rcx
  jae    L78
L5:
  movzbl (%rax),%edx
  test   %dl,%dl
  je     L78
  jns    L73
  mov    %edx,%esi
  and    $0xffffffe0,%esi
  cmp    $0xc0,%sil
  je     L233
  mov    %edx,%esi
  and    $0xfffffff0,%esi
  cmp    $0xe0,%sil
  je     L1
  mov    %edx,%esi
  and    $0xfffffff8,%esi
  cmp    $0xf0,%sil
  jne    L78
  mov    %rbp,%rsi
  sub    %rcx,%rsi
  cmp    $0x3,%rsi
  jbe    L78
  movzbl 0x1(%rax),%ecx
  and    $0x7,%edx
  lea    0x1(%rax),%rsi
  mov    %ecx,%edi
  and    $0xffffffc0,%edi
  cmp    $0x80,%dil
  jne    L78
  shl    $0x6,%edx
  and    $0x3f,%ecx
  mov    $0x10000,%r8d
  or     %edx,%ecx
L125:
  movzbl 0x1(%rsi),%edx
  mov    %edx,%edi
  and    $0xffffffc0,%edi
  cmp    $0x80,%dil
  jne    L78
  and    $0x3f,%edx
  shl    $0x6,%ecx
  or     %edx,%ecx
  movzbl 0x2(%rsi),%edx
  mov    %edx,%edi
  and    $0xffffffc0,%edi
  cmp    $0x80,%dil
  jne    L78
  shl    $0x6,%ecx
  and    $0x3f,%edx
  or     %ecx,%edx
  cmp    %edx,%r8d
  ja     L78
  cmp    $0x10ffff,%edx
  ja     L78
  mov    %edx,%ecx
  and    $0xfffff800,%ecx
  cmp    $0xd800,%ecx
  je     L78
  lea    -0xfdd0(%rdx),%ecx
  cmp    $0x1f,%ecx
  jbe    L78
  and    $0xfffe,%edx
  cmp    $0xfffe,%edx
  je     L78
  lea    0x2(%rsi),%rax
  jmp    L73
  cs nopw 0x0(%rax,%rax,1)
L233:
  mov    %rbp,%rsi
  sub    %rcx,%rsi
  cmp    $0x1,%rsi
  je     L78
  and    $0x1e,%edx
  je     L78
  movzbl 0x1(%rax),%edx
  and    $0xffffffc0,%edx
  cmp    $0x80,%dl
  je     L140
L78:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  ret
  nopl   0x0(%rax)
L140:
  add    $0x1,%rax
  jmp    L73
  nopl   0x0(%rax)
L1:
  mov    %rbp,%rsi
  sub    %rcx,%rsi
  cmp    $0x2,%rsi
  jbe    L78
  mov    %edx,%ecx
  mov    %rax,%rsi
  mov    $0x800,%r8d
  and    $0xf,%ecx
  jmp    L125
```

assistant: ```c
const char *fast_validate_len(const char *str, size_t max_len) {
  unsigned int val = 0;
  unsigned int min = 0;
  const char *p;
  assert(max_len >= 0);
  for (p = str; ((size_t)(p - str) < max_len) && *p; p++) {
    if (*(unsigned char *)p < 128)
      ;
    else {
      const char *last;
      last = p;
      if ((*(unsigned char *)p & 0xe0) == 0xc0) {
        if (max_len - (p - str) < 2)
          goto error;
        if ((*(unsigned char *)p & 0x1e) == 0)
          goto error;
        p++;
        if ((*(unsigned char *)p & 0xc0) != 0x80)
          goto error;
      } else {
        if ((*(unsigned char *)p & 0xf0) == 0xe0) {
          if (max_len - (p - str) < 3)
            goto error;
          min = (1 << 11);
          val = *(unsigned char *)p & 0x0f;
          goto TWO_REMAINING;
        } else if ((*(unsigned char *)p & 0xf8) == 0xf0) {
          if (max_len - (p - str) < 4)
            goto error;
          min = (1 << 16);
          val = *(unsigned char *)p & 0x07;
        } else
          goto error;
        p++;
        do {
          if ((*(unsigned char *)p & 0xc0) != 0x80)
            goto error;
          val <<= 6;
          val |= (*(unsigned char *)p) & 0x3f;
        } while (0);
      TWO_REMAINING:
        p++;
        do {
          if ((*(unsigned char *)p & 0xc0) != 0x80)
            goto error;
          val <<= 6;
          val |= (*(unsigned char *)p) & 0x3f;
        } while (0);
        p++;
        do {
          if ((*(unsigned char *)p & 0xc0) != 0x80)
            goto error;
          val <<= 6;
          val |= (*(unsigned char *)p) & 0x3f;
        } while (0);
        if (val < min)
          goto error;
        if (!((val) < 0x110000 && (((val)&0xFFFFF800) != 0xD800) && ((val) < 0xFDD0 || (val) > 0xFDEF) && ((val)&0xFFFE) != 0xFFFE))
          goto error;
      }
      continue;
    error:
      return last;
    }
  }
  return p;
}
```