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

```asm
<adler32>:
  endbr64
  push   %r15
  mov    %rdi,%rax
  mov    %rsi,%rcx
  movzwl %di,%r15d
  push   %r14
  shr    $0x10,%rax
  push   %r13
  movzwl %ax,%eax
  push   %r12
  push   %rbp
  push   %rbx
  mov    %edx,-0x8(%rsp)
  mov    %rax,-0x18(%rsp)
  cmp    $0x1,%edx
  je     L239
  test   %rsi,%rsi
  je     L219
  cmp    $0xf,%edx
  jbe    L75
  lea    0x15b0(%rsi),%rbx
  mov    %rbx,-0x10(%rsp)
  cmp    $0x15af,%edx
  jbe    L27
L331:
  mov    -0x10(%rsp),%rax
  lea    -0x15b0(%rax),%rsi
  mov    -0x8(%rsp),%eax
  mov    %eax,-0x4(%rsp)
  sub    $0x15b0,%eax
  mov    %eax,-0x8(%rsp)
  nopl   0x0(%rax,%rax,1)
L251:
  movzbl (%rsi),%eax
  movzbl 0x1(%rsi),%r14d
  add    $0x10,%rsi
  movzbl -0xe(%rsi),%r13d
  movzbl -0xd(%rsi),%r12d
  add    %r15,%rax
  movzbl -0xc(%rsi),%ebp
  movzbl -0xb(%rsi),%ebx
  add    %rax,%r14
  movzbl -0xa(%rsi),%r11d
  movzbl -0x9(%rsi),%edx
  add    %r14,%r13
  add    %r14,%rax
  movzbl -0x7(%rsi),%r10d
  movzbl -0x6(%rsi),%r9d
  add    %r13,%r12
  add    %r13,%rax
  movzbl -0x5(%rsi),%r8d
  movzbl -0x3(%rsi),%ecx
  add    %r12,%rbp
  add    %r12,%rax
  movzbl -0x1(%rsi),%r15d
  add    %rbp,%rbx
  add    %rbp,%rax
  add    %rbx,%r11
  add    %rbx,%rax
  lea    (%rdx,%r11,1),%rdi
  movzbl -0x8(%rsi),%edx
  add    %r11,%rax
  mov    %rdi,-0x28(%rsp)
  add    -0x28(%rsp),%rax
  add    %rdi,%rdx
  movzbl -0x4(%rsi),%edi
  add    %rdx,%r10
  mov    %rdx,-0x20(%rsp)
  add    -0x20(%rsp),%rax
  add    %r10,%r9
  add    %r10,%rax
  movzbl -0x2(%rsi),%edx
  add    %r9,%r8
  add    %r9,%rax
  add    %r8,%rdi
  add    %r8,%rax
  add    %rdi,%rcx
  add    %rdi,%rax
  add    %rcx,%rdx
  add    %rcx,%rax
  add    %rdx,%r15
  add    %rdx,%rax
  add    %r15,%rax
  add    %rax,-0x18(%rsp)
  mov    -0x10(%rsp),%rax
  mov    %rax,%rcx
  cmp    %rax,%rsi
  jne    L251
  movabs $0xf00e10d2fc5cd,%rax
  mov    -0x18(%rsp),%rbx
  mul    %r15
  mov    %r15,%rax
  sub    %rdx,%rax
  shr    %rax
  add    %rax,%rdx
  shr    $0xf,%rdx
  imul   $0xfff1,%rdx,%rax
  sub    %rax,%r15
  movabs $0xf00e10d2fc5cd,%rax
  mul    %rbx
  mov    %rbx,%rax
  sub    %rdx,%rax
  shr    %rax
  add    %rax,%rdx
  shr    $0xf,%rdx
  imul   $0xfff1,%rdx,%rax
  sub    %rax,%rbx
  lea    0x15b0(%rsi),%rax
  cmpl   $0x15af,-0x8(%rsp)
  mov    %rbx,-0x18(%rsp)
  mov    %rax,-0x10(%rsp)
  ja     L331
  mov    -0x8(%rsp),%eax
  test   %eax,%eax
  jne    L281
L405:
  mov    -0x18(%rsp),%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  shl    $0x10,%rax
  pop    %r13
  pop    %r14
  or     %r15,%rax
  pop    %r15
  ret
L75:
  test   %edx,%edx
  je     L270
  movzbl (%rsi),%eax
  add    %rax,%r15
  add    %r15,-0x18(%rsp)
  mov    -0x18(%rsp),%rbx
  cmp    $0x1,%edx
  je     L270
  movzbl 0x1(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x2,%edx
  je     L270
  movzbl 0x2(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x3,%edx
  je     L270
  movzbl 0x3(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x4,%edx
  je     L270
  movzbl 0x4(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x5,%edx
  je     L270
  movzbl 0x5(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x6,%edx
  je     L270
  movzbl 0x6(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x7,%edx
  je     L270
  movzbl 0x7(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x8,%edx
  je     L270
  movzbl 0x8(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0x9,%edx
  je     L270
  movzbl 0x9(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0xa,%edx
  je     L270
  movzbl 0xa(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0xb,%edx
  je     L270
  movzbl 0xb(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0xc,%edx
  je     L270
  movzbl 0xc(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0xd,%edx
  je     L270
  movzbl 0xd(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
  cmp    $0xe,%edx
  je     L270
  movzbl 0xe(%rsi),%eax
  add    %rax,%r15
  add    %r15,%rbx
  mov    %rbx,-0x18(%rsp)
L270:
  cmp    $0xfff0,%r15
  lea    -0xfff1(%r15),%rax
  mov    -0x18(%rsp),%rcx
  movabs $0xf00e10d2fc5cd,%rdx
  cmova  %rax,%r15
  mov    -0x18(%rsp),%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  mul    %rdx
  mov    %rcx,%rax
  pop    %r13
  pop    %r14
  sub    %rdx,%rax
  shr    %rax
  add    %rdx,%rax
  mov    %rcx,%rdx
  shr    $0xf,%rax
  imul   $0xfff1,%rax,%rax
  sub    %rax,%rdx
  mov    %rdx,%rax
  shl    $0x10,%rax
  or     %r15,%rax
  pop    %r15
  ret
L239:
  movzbl (%rsi),%edx
  add    %r15,%rdx
  cmp    $0xfff0,%rdx
  lea    -0xfff1(%rdx),%rax
  cmova  %rax,%rdx
  mov    -0x18(%rsp),%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  add    %rdx,%rax
  pop    %r13
  pop    %r14
  cmp    $0xfff0,%rax
  lea    -0xfff1(%rax),%rcx
  pop    %r15
  cmova  %rcx,%rax
  shl    $0x10,%rax
  or     %rdx,%rax
  ret
L281:
  cmp    $0xf,%eax
  jbe    L157
L27:
  mov    -0x8(%rsp),%eax
  sub    $0x10,%eax
  shr    $0x4,%eax
  mov    %eax,-0x4(%rsp)
  add    $0x1,%eax
  shl    $0x4,%rax
  add    %rcx,%rax
  mov    %rax,-0x10(%rsp)
L99:
  movzbl (%rcx),%eax
  movzbl 0x1(%rcx),%r14d
  add    $0x10,%rcx
  movzbl -0xe(%rcx),%r13d
  movzbl -0xd(%rcx),%r12d
  add    %r15,%rax
  movzbl -0xc(%rcx),%ebp
  movzbl -0xb(%rcx),%ebx
  add    %rax,%r14
  movzbl -0xa(%rcx),%r11d
  movzbl -0x9(%rcx),%r10d
  add    %r14,%r13
  movzbl -0x8(%rcx),%r9d
  add    %r14,%rax
  movzbl -0x7(%rcx),%r8d
  add    %r13,%r12
  add    %r13,%rax
  movzbl -0x6(%rcx),%edx
  movzbl -0x3(%rcx),%esi
  add    %r12,%rbp
  add    %r12,%rax
  movzbl -0x1(%rcx),%r15d
  add    %rbp,%rbx
  add    %rbp,%rax
  add    %rbx,%r11
  add    %rbx,%rax
  add    %r11,%r10
  add    %r11,%rax
  add    %r10,%r9
  add    %r10,%rax
  add    %r9,%r8
  add    %r9,%rax
  lea    (%rdx,%r8,1),%rdi
  movzbl -0x5(%rcx),%edx
  add    %r8,%rax
  mov    %rdi,-0x28(%rsp)
  add    -0x28(%rsp),%rax
  add    %rdi,%rdx
  movzbl -0x4(%rcx),%edi
  mov    %rdx,-0x20(%rsp)
  add    -0x20(%rsp),%rax
  add    %rdx,%rdi
  movzbl -0x2(%rcx),%edx
  add    %rdi,%rsi
  add    %rdi,%rax
  add    %rsi,%rdx
  add    %rsi,%rax
  add    %rdx,%r15
  add    %rdx,%rax
  add    %r15,%rax
  add    %rax,-0x18(%rsp)
  cmp    -0x10(%rsp),%rcx
  jne    L99
  mov    -0x4(%rsp),%eax
  mov    -0x8(%rsp),%ecx
  shl    $0x4,%eax
  neg    %eax
  lea    -0x11(%rcx,%rax,1),%eax
  and    $0xf,%ecx
  je     L252
L153:
  mov    -0x10(%rsp),%rbx
  movzbl (%rbx),%edx
  add    %rdx,%r15
  add    %r15,-0x18(%rsp)
  mov    -0x18(%rsp),%rcx
  test   %eax,%eax
  je     L252
  movzbl 0x1(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x1,%eax
  je     L252
  movzbl 0x2(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x2,%eax
  je     L252
  movzbl 0x3(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x3,%eax
  je     L252
  movzbl 0x4(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x4,%eax
  je     L252
  movzbl 0x5(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x5,%eax
  je     L252
  movzbl 0x6(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x6,%eax
  je     L252
  movzbl 0x7(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x7,%eax
  je     L252
  movzbl 0x8(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x8,%eax
  je     L252
  movzbl 0x9(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0x9,%eax
  je     L252
  movzbl 0xa(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0xa,%eax
  je     L252
  movzbl 0xb(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0xb,%eax
  je     L252
  movzbl 0xc(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0xc,%eax
  je     L252
  movzbl 0xd(%rbx),%edx
  add    %rdx,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
  cmp    $0xd,%eax
  je     L252
  movzbl 0xe(%rbx),%eax
  add    %rax,%r15
  add    %r15,%rcx
  mov    %rcx,-0x18(%rsp)
L252:
  movabs $0xf00e10d2fc5cd,%rcx
  mov    %r15,%rax
  mul    %rcx
  mov    %r15,%rax
  sub    %rdx,%rax
  shr    %rax
  add    %rdx,%rax
  shr    $0xf,%rax
  imul   $0xfff1,%rax,%rax
  sub    %rax,%r15
  mov    -0x18(%rsp),%rax
  mul    %rcx
  mov    -0x18(%rsp),%rcx
  mov    %rcx,%rax
  sub    %rdx,%rax
  shr    %rax
  add    %rdx,%rax
  shr    $0xf,%rax
  imul   $0xfff1,%rax,%rax
  sub    %rax,%rcx
  mov    %rcx,-0x18(%rsp)
  jmp    L405
L219:
  pop    %rbx
  mov    $0x1,%eax
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L157:
  mov    -0x4(%rsp),%eax
  mov    %rsi,-0x10(%rsp)
  sub    $0x15b1,%eax
  jmp    L153
```

assistant: ```c
unsigned long adler32(unsigned long adler, const unsigned char *buf, unsigned int len) {
  unsigned long sum2;
  unsigned n;
  sum2 = (adler >> 16) & 0xffff;
  adler &= 0xffff;
  if (len == 1) {
    adler += buf[0];
    if (adler >= 65521UL)
      adler -= 65521UL;
    sum2 += adler;
    if (sum2 >= 65521UL)
      sum2 -= 65521UL;
    return adler | (sum2 << 16);
  }
  if (buf == NULL)
    return 1L;
  if (len < 16) {
    while (len--) {
      adler += *buf++;
      sum2 += adler;
    }
    if (adler >= 65521UL)
      adler -= 65521UL;
    sum2 %= 65521UL;
    return adler | (sum2 << 16);
  }
  while (len >= 5552) {
    len -= 5552;
    n = 5552 / 16;
    do {
      {
        adler += (buf)[0];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[0 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      {
        adler += (buf)[0 + 4];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 4 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[0 + 4 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 4 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      ;
      {
        adler += (buf)[8];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[8 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      {
        adler += (buf)[8 + 4];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 4 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[8 + 4 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 4 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      ;
      ;
      buf += 16;
    } while (--n);
    adler %= 65521UL;
    sum2 %= 65521UL;
  }
  if (len) {
    while (len >= 16) {
      len -= 16;
      {
        adler += (buf)[0];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[0 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      {
        adler += (buf)[0 + 4];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 4 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[0 + 4 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[0 + 4 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      ;
      {
        adler += (buf)[8];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[8 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      {
        adler += (buf)[8 + 4];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 4 + 1];
        sum2 += adler;
      };
      ;
      {
        adler += (buf)[8 + 4 + 2];
        sum2 += adler;
      };
      {
        adler += (buf)[8 + 4 + 2 + 1];
        sum2 += adler;
      };
      ;
      ;
      ;
      ;
      buf += 16;
    }
    while (len--) {
      adler += *buf++;
      sum2 += adler;
    }
    adler %= 65521UL;
    sum2 %= 65521UL;
  }
  return adler | (sum2 << 16);
}
```