user: 请将以下的汇编代码转换成C语言代码:

```asm
<decompress_lz>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,%r14
  mov    %rsi,%r12
  mov    %rdx,%r13
  mov    %fs:0x28,%rax
  mov    %rax,0x28(%rsp)
  xor    %eax,%eax
  mov    (%rsi),%edi
  call   <le32toh@plt>
  mov    %rax,%r15
  lea    -0x1(%r14),%rax
  mov    %rax,0x18(%rsp)
  lea    0x4(%r12),%rax
  mov    %rax,0x20(%rsp)
  movl   $0x0,0x14(%rsp)
  movl   $0x0,0xc(%rsp)
  lea    0x14(%rsp),%rbp
L314:
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  test   %eax,%eax
  je     L127
  mov    0x20(%rsp),%rdx
  mov    %rdx,%rax
  sub    %r12,%rax
  sub    $0x4,%rax
  cmp    %r13,%rax
  jae    L225
  mov    0x18(%rsp),%rax
  lea    (%r14,%r15,1),%rcx
  cmp    %rcx,%rax
  jae    L6
  lea    0x1(%rdx),%rcx
  mov    %rcx,0x20(%rsp)
  lea    0x1(%rax),%rcx
  mov    %rcx,0x18(%rsp)
  movzbl (%rdx),%edx
  mov    %dl,0x1(%rax)
  jmp    L314
L127:
  mov    $0x1,%ebx
L187:
  add    %ebx,%ebx
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  add    %eax,%ebx
  mov    0x20(%rsp),%rax
  sub    %r12,%rax
  sub    $0x4,%rax
  cmp    %r13,%rax
  jae    L77
  cmp    $0x1000002,%ebx
  jg     L76
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  test   %eax,%eax
  jne    L71
  lea    -0x2(%rbx,%rbx,1),%ebx
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  add    %eax,%ebx
  jmp    L187
L71:
  cmp    $0x2,%ebx
  je     L50
  mov    0x20(%rsp),%rdx
  mov    %rdx,%rax
  sub    %r12,%rax
  sub    $0x4,%rax
  cmp    %r13,%rax
  jae    L99
  sub    $0x3,%ebx
  shl    $0x8,%ebx
  lea    0x1(%rdx),%rax
  mov    %rax,0x20(%rsp)
  movzbl (%rdx),%edx
  lea    (%rdx,%rbx,1),%ecx
  mov    %ecx,0xc(%rsp)
  cmp    $0xffffffff,%ecx
  je     L226
  testb  $0x1,0xc(%rsp)
  je     L227
L89:
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  test   %eax,%eax
  je     L107
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  lea    0x3(%rax),%edx
  jmp    L168
L50:
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  test   %eax,%eax
  je     L89
L227:
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  lea    0x1(%rax),%edx
L168:
  mov    0xc(%rsp),%eax
  mov    %eax,%esi
  sar    %esi
  cmp    $0xa01,%eax
  setg   %al
  movzbl %al,%eax
  add    %eax,%edx
  mov    0x18(%rsp),%rax
  movslq %edx,%rcx
  add    %rax,%rcx
  lea    (%r14,%r15,1),%rdi
  cmp    %rdi,%rcx
  jae    L91
  movslq %esi,%rcx
  sub    %rcx,%rax
  cmp    %rax,%r14
  ja     L51
  lea    0x18(%rsp),%rdi
  call   <copy@plt>
  jmp    L314
L226:
  sub    %r12,%rax
  sub    $0x4,%rax
  cmp    %r13,%rax
  setae  %al
  movzbl %al,%eax
  neg    %eax
  jmp    L124
L107:
  mov    $0x1,%ebx
L97:
  add    %ebx,%ebx
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  add    %eax,%ebx
  lea    (%r12,%r13,1),%rax
  cmp    %rax,0x20(%rsp)
  jae    L36
  movslq %ebx,%rax
  cmp    %r15,%rax
  jae    L106
  lea    0x20(%rsp),%rdi
  mov    %rbp,%rsi
  call   <next@plt>
  test   %eax,%eax
  je     L97
  lea    0x3(%rbx),%edx
  jmp    L168
L225:
  mov    $0xfffffffa,%eax
  jmp    L124
L6:
  mov    $0xfffffff9,%eax
  jmp    L124
L77:
  mov    $0xfffffff7,%eax
L124:
  mov    0x28(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L170
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L76:
  mov    $0xfffffff6,%eax
  jmp    L124
L99:
  mov    $0xfffffff8,%eax
  jmp    L124
L36:
  mov    $0xfffffffc,%eax
  jmp    L124
L106:
  mov    $0xfffffffb,%eax
  jmp    L124
L91:
  mov    $0xfffffffe,%eax
  jmp    L124
L51:
  mov    $0xfffffffd,%eax
  jmp    L124
L170:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int decompress_lz(char *dst, char *src, size_t src_length) {
  size_t dst_length = le32toh(*((uint32_t *)src));
  char *out = dst - 1;
  char *in = src + 4;
  uint16_t ctrl = 0;
  uint32_t off_copy = 0;
  while (1) {
    while (next(&in, &ctrl)) {
      if (in - src - 4 >= src_length)
        return -6;
      if (out >= dst + dst_length)
        return -7;
      *(++out) = *in++;
    }
    uint32_t off = 1;
    int32_t lng = 0;
    while (1) {
      off *= 2;
      off += next(&in, &ctrl);
      if (in - src - 4 >= src_length)
        return -9;
      if (off > 0x1000002)
        return -10;
      if (next(&in, &ctrl)) {
        break;
      }
      off--;
      off *= 2;
      off += next(&in, &ctrl);
    }
    if (off == 2) {
      lng = next(&in, &ctrl);
      off = off_copy;
    } else {
      if (in - src - 4 >= src_length)
        return -8;
      off -= 3;
      off <<= 8;
      off += (unsigned char)(*in++);
      if (off == -1) {
        if (in - src - 4 >= src_length)
          return -1;
        return 0;
      }
      lng = (off ^ 1) & 1;
    }
    if (lng == 0) {
      if (next(&in, &ctrl)) {
        lng = 3 + next(&in, &ctrl);
      } else {
        ++lng;
        do {
          lng *= 2;
          lng += next(&in, &ctrl);
          if (in >= src + src_length)
            return -4;
          if (lng >= dst_length)
            return -5;
        } while (!next(&in, &ctrl));
        lng += 3;
      }
    } else {
      lng = 1 + next(&in, &ctrl);
    }
    off_copy = off;
    if ((off >> 1) > 0x500)
      ++lng;
    if ((out + lng) >= (dst + dst_length))
      return -2;
    if ((out - (off >> 1)) < dst)
      return -3;
    ;
    copy(&out, off >> 1, lng);
  }
}
```