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

```asm
<zend_hash>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    $0x1505,%ebx
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x28(%rbp)
  jne    L24
  mov    $0x0,%eax
  jmp    L25
L0:
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  subq   $0x8,-0x18(%rbp)
L24:
  cmpq   $0x7,-0x18(%rbp)
  ja     L0
  cmpq   $0x7,-0x18(%rbp)
  ja     L46
  mov    -0x18(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  lea    D3(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  cltq
  lea    D3(%rip),%rdx
  add    %rdx,%rax
  notrack jmp *%rax
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  mov    %rbx,%rax
  shl    $0x5,%rax
  lea    (%rbx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movsbq %al,%rax
  lea    (%rcx,%rax,1),%rbx
  jmp    L46
  nop
L46:
  mov    %rbx,%rax
L25:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
unsigned long int zend_hash(const char *key) {
  register unsigned long int hash = 5381;
  size_t len = strlen(key);
  if (!key) {
    return 0;
  }
  for (; len >= 8; len -= 8) {
    hash = ((hash << 5) + hash) + *key++;
    hash = ((hash << 5) + hash) + *key++;
    hash = ((hash << 5) + hash) + *key++;
    hash = ((hash << 5) + hash) + *key++;
    hash = ((hash << 5) + hash) + *key++;
    hash = ((hash << 5) + hash) + *key++;
    hash = ((hash << 5) + hash) + *key++;
    hash = ((hash << 5) + hash) + *key++;
  }
  switch (len) {
  case 7:
    hash = ((hash << 5) + hash) + *key++;
  case 6:
    hash = ((hash << 5) + hash) + *key++;
  case 5:
    hash = ((hash << 5) + hash) + *key++;
  case 4:
    hash = ((hash << 5) + hash) + *key++;
  case 3:
    hash = ((hash << 5) + hash) + *key++;
  case 2:
    hash = ((hash << 5) + hash) + *key++;
  case 1:
    hash = ((hash << 5) + hash) + *key++;
    break;
  case 0:
    break;
  }
  return hash;
}
```