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

```asm
<wma_utf16toutf8>:
  endbr64
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  movslq %esi,%rbx
  test   %ebx,%ebx
  je     L9
  lea    0x1(%rbx,%rbx,1),%r14d
  mov    %rdi,%r13
  mov    %r14d,%edi
  call   <malloc@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  je     L9
  mov    %r14d,%edx
  xor    %esi,%esi
  mov    %rax,%rdi
  mov    %rax,%r12
  call   <memset@plt>
  lea    0x0(%r13,%rbx,1),%r9
  lea    0x2(%r13),%rax
  cmp    %rax,%r9
  jb     L20
  sub    $0x2,%rbx
  lea    0x4(%r13),%rsi
  mov    %rbp,%rcx
  and    $0xfffffffffffffffe,%rbx
  lea    0x6(%r13,%rbx,1),%r8
  jmp    L113
  nopl   0x0(%rax,%rax,1)
L118:
  lea    0x1(%rcx),%rdi
  cmp    $0x7f,%eax
  jg     L37
  mov    %al,(%rcx)
  mov    %rdi,%rcx
L123:
  add    $0x2,%rsi
  cmp    %r8,%rsi
  je     L20
L113:
  movzwl -0x4(%rsi),%eax
  mov    %eax,%edi
  mov    %eax,%edx
  and    $0xfc00,%di
  cmp    $0xd800,%di
  jne    L118
  cmp    %rsi,%r9
  jb     L89
  movzwl (%rsi),%edx
  mov    %edx,%edi
  and    $0xfc00,%di
  cmp    $0xdc00,%di
  jne    L89
  shl    $0xa,%eax
  and    $0x3ff,%edx
  lea    0x1(%rcx),%rdi
  mov    $0x3,%r10d
  and    $0xffc00,%eax
  or     %eax,%edx
  lea    0x10000(%rdx),%eax
  mov    %eax,%edx
  shr    $0x12,%edx
  or     $0xfffffff0,%edx
L137:
  lea    -0x1(%r10),%r11d
  mov    %dl,(%rcx)
  mov    %eax,%edx
  lea    (%r11,%r11,2),%ecx
  add    %ecx,%ecx
  shr    %cl,%edx
  sub    $0x6,%ecx
  and    $0x3f,%edx
  or     $0xffffff80,%edx
  mov    %dl,(%rdi)
  mov    %eax,%edx
  shr    %cl,%edx
  and    $0x3f,%edx
  or     $0xffffff80,%edx
  mov    %dl,0x1(%rdi)
  cmp    $0x1,%r11d
  je     L19
  and    $0x3f,%eax
  or     $0xffffff80,%eax
  mov    %al,0x2(%rdi)
L19:
  lea    (%rdi,%r10,1),%rcx
  jmp    L123
L89:
  mov    $0x5,%edi
  lea    D2(%rip),%rdx
  mov    $0x8,%esi
  call   <err_log@plt>
  mov    %rbp,%rdi
  call   <free@plt>
L9:
  xor    %r12d,%r12d
L20:
  pop    %rbx
  mov    %r12,%rax
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
  xchg   %ax,%ax
L37:
  mov    %eax,%r10d
  shr    $0x6,%r10d
  cmp    $0x7ff,%eax
  ja     L5
  mov    %r10d,%eax
  and    $0x3f,%edx
  add    $0x2,%rcx
  or     $0xffffffc0,%eax
  or     $0xffffff80,%edx
  mov    %al,-0x2(%rcx)
  mov    %dl,-0x1(%rcx)
  jmp    L123
  nopl   0x0(%rax)
L5:
  mov    %eax,%edx
  mov    $0x2,%r10d
  shr    $0xc,%edx
  or     $0xffffffe0,%edx
  jmp    L137
```

tool_calls: name: extract_symbolic_data
arguments: data_tag: D2
type_guessed: string

tool: D2: Invalid utf-16 in file


assistant: ```c
char *wma_utf16toutf8(unsigned char *utf16, int len) {
  char *utf8;
  unsigned char *src = utf16;
  char *dst;
  unsigned int w1, w2;
  int bytes;
  if (!len)
    return NULL;
  utf8 = (char *)malloc(len * 2 + 1);
  if (!utf8)
    return NULL;
  memset(utf8, 0x0, len * 2 + 1);
  dst = utf8;
  while ((src + 2) <= utf16 + len) {
    w1 = src[1] << 8 | src[0];
    src += 2;
    if ((w1 & 0xFC00) == 0xD800) {
      if (src + 2 > utf16 + len) {
        err_log(5, 0x00000008, "Invalid utf-16 in file\n");
        free(utf8);
        return NULL;
      }
      w2 = src[3] << 8 | src[2];
      if ((w2 & 0xFC00) != 0xDC00) {
        err_log(5, 0x00000008, "Invalid utf-16 in file\n");
        free(utf8);
        return NULL;
      }
      w1 = w1 & 0x03FF;
      w1 = w1 << 10;
      w1 = w1 | (w2 & 0x03FF);
      w1 += 0x10000;
    }
    if (w1 < 0x80) {
      *dst++ = w1;
      bytes = 0;
    } else if (w1 < 0x800) {
      *dst++ = 0xC0 | (w1 >> 6);
      bytes = 1;
    } else if (w1 < 0x10000) {
      *dst++ = 0xE0 | (w1 >> 12);
      bytes = 2;
    } else {
      *dst++ = 0xF0 | (w1 >> 18);
      bytes = 3;
    }
    while (bytes) {
      *dst++ = 0x80 | ((w1 >> (6 * (bytes - 1))) & 0x3f);
      bytes--;
    }
  }
  return utf8;
}
```