user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<mbrtowc>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %rcx,-0x50(%rbp)
  cmpq   $0x0,-0x48(%rbp)
  je     L227
  cmpq   $0x0,-0x40(%rbp)
  je     L227
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L276
L227:
  cmpq   $0x0,-0x38(%rbp)
  je     L263
  mov    -0x38(%rbp),%rax
  movl   $0x0,(%rax)
L263:
  mov    $0x0,%eax
  jmp    L196
L276:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,-0x28(%rbp)
  mov    -0x28(%rbp),%eax
  and    $0x80,%eax
  test   %eax,%eax
  jne    L325
  cmpq   $0x0,-0x38(%rbp)
  je     L189
  mov    -0x38(%rbp),%rax
  mov    -0x28(%rbp),%edx
  mov    %edx,(%rax)
L189:
  mov    $0x1,%eax
  jmp    L196
L325:
  mov    -0x28(%rbp),%eax
  and    $0x40,%eax
  test   %eax,%eax
  jne    L255
  mov    D21(%rip),%rax
  mov    (%rax),%rdx
  mov    D4(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffffffffffff,%rax
  jmp    L196
L255:
  mov    -0x28(%rbp),%eax
  and    $0x20,%eax
  test   %eax,%eax
  jne    L172
  andl   $0x1f,-0x28(%rbp)
  movq   $0x1,-0x20(%rbp)
  jmp    L155
L172:
  mov    -0x28(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  jne    L259
  andl   $0xf,-0x28(%rbp)
  movq   $0x2,-0x20(%rbp)
  jmp    L155
L259:
  mov    -0x28(%rbp),%eax
  and    $0x8,%eax
  test   %eax,%eax
  jne    L30
  andl   $0x7,-0x28(%rbp)
  movq   $0x3,-0x20(%rbp)
  jmp    L155
L30:
  mov    -0x28(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  jne    L77
  andl   $0x3,-0x28(%rbp)
  movq   $0x4,-0x20(%rbp)
  jmp    L155
L77:
  mov    -0x28(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L254
  andl   $0x1,-0x28(%rbp)
  movq   $0x5,-0x20(%rbp)
  jmp    L155
L254:
  mov    -0x28(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  jne    L161
  mov    D21(%rip),%rax
  mov    (%rax),%rdx
  mov    D4(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffffffffffff,%rax
  jmp    L196
L161:
  mov    D21(%rip),%rax
  mov    (%rax),%rdx
  mov    D4(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffffffffffff,%rax
  jmp    L196
L155:
  mov    -0x40(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x48(%rbp),%rax
  cmp    -0x20(%rbp),%rax
  ja     L4
  mov    -0x40(%rbp),%rdx
  mov    -0x48(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  jmp    L56
L133:
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  movsbl %al,%eax
  and    $0xc0,%eax
  cmp    $0x80,%eax
  je     L56
  mov    D21(%rip),%rax
  mov    (%rax),%rdx
  mov    D4(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffffffffffff,%rax
  jmp    L196
L56:
  mov    -0x18(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jne    L133
  mov    $0xfffffffffffffffe,%rax
  jmp    L196
L4:
  mov    -0x18(%rbp),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x10(%rbp)
  jmp    L271
L264:
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,-0x24(%rbp)
  mov    -0x24(%rbp),%eax
  and    $0xc0,%eax
  cmp    $0x80,%eax
  je     L113
  mov    D21(%rip),%rax
  mov    (%rax),%rdx
  mov    D4(%rip),%rax
  mov    %rdx,(%rax)
  mov    $0xffffffffffffffff,%rax
  jmp    L196
L113:
  mov    -0x28(%rbp),%eax
  shl    $0x6,%eax
  mov    %eax,%edx
  mov    -0x24(%rbp),%eax
  and    $0x3f,%eax
  or     %edx,%eax
  mov    %eax,-0x28(%rbp)
L271:
  mov    -0x18(%rbp),%rax
  cmp    -0x10(%rbp),%rax
  jne    L264
  cmpq   $0x0,-0x38(%rbp)
  je     L186
  mov    -0x38(%rbp),%rax
  mov    -0x28(%rbp),%edx
  mov    %edx,(%rax)
L186:
  mov    -0x18(%rbp),%rax
  sub    -0x40(%rbp),%rax
L196:
  pop    %rbp
  ret
```

assistant: ```c
size_t mbrtowc(wchar_t *restrict pwc, char const *restrict s, size_t n, mbstate_t *restrict ps) {
  if (!n || !s || !*s) {
    if (pwc)
      *pwc = 0;
    return 0;
  }
  wchar_t c = *s;
  size_t len;
  if (!(c & 0x80)) {
    if (pwc)
      *pwc = c;
    return 1;
  } else if (!(c & 0x40))
    return errno = EILSEQ, (size_t)-1;
  else if (!(c & 0x20))
    c = c & 0x1F, len = 1;
  else if (!(c & 0x10))
    c = c & 0x0F, len = 2;
  else if (!(c & 0x08))
    c = c & 0x07, len = 3;
  else if (!(c & 0x04))
    c = c & 0x03, len = 4;
  else if (!(c & 0x02))
    c = c & 0x01, len = 5;
  else if (!(c & 0x01))
    return errno = EILSEQ, (size_t)-1;
  else
    return errno = EILSEQ, (size_t)-1;
  char const *itr = s + 1;
  if (n <= len) {
    char const *end = s + n;
    while (itr != end) {
      if ((*itr++ & 0xC0) != 0x80)
        return errno = EILSEQ, (size_t)-1;
    }
    return (size_t)-2;
  }
  char const *end = itr + len;
  while (itr != end) {
    wchar_t i = *itr++;
    if ((i & 0xC0) != 0x80)
      return errno = EILSEQ, (size_t)-1;
    c = (c << 6) | (i & 0x3F);
  }
  if (pwc)
    *pwc = c;
  return itr - s;
}
```