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

```asm
<utf8_decode>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  sar    $0x3,%al
  movsbl %al,%eax
  cltq
  lea    D24(%rip),%rdx
  movzbl (%rax,%rdx,1),%eax
  movsbl %al,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  movslq %eax,%rdx
  cmpl   $0x0,-0xc(%rbp)
  sete   %al
  movzbl %al,%eax
  add    %rax,%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%ecx
  mov    -0xc(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rdx
  lea    D12(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  and    %ecx,%eax
  shl    $0x12,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  shl    $0xc,%eax
  and    $0x3f000,%eax
  or     %eax,%edx
  mov    -0x20(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x18(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  shl    $0x6,%eax
  and    $0xfc0,%eax
  or     %eax,%edx
  mov    -0x20(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x18(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  and    $0x3f,%eax
  or     %eax,%edx
  mov    -0x20(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%edx
  mov    -0xc(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rcx
  lea    D44(%rip),%rax
  mov    (%rcx,%rax,1),%eax
  mov    %eax,%ecx
  sar    %cl,%edx
  mov    -0x20(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%edx
  mov    -0xc(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rcx
  lea    D13(%rip),%rax
  mov    (%rcx,%rax,1),%eax
  cmp    %eax,%edx
  jge    L10
  mov    $0x40,%edx
  jmp    L30
L10:
  mov    $0x0,%edx
L30:
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x20(%rbp),%rax
  mov    (%rax),%eax
  sar    $0xb,%eax
  cmp    $0x1b,%eax
  jne    L3
  mov    $0x80,%eax
  jmp    L34
L3:
  mov    $0x0,%eax
L34:
  or     %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x20(%rbp),%rax
  mov    (%rax),%eax
  cmp    $0x10ffff,%eax
  jle    L15
  mov    $0x100,%eax
  jmp    L52
L15:
  mov    $0x0,%eax
L52:
  or     %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x18(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  sar    $0x2,%eax
  and    $0x30,%eax
  or     %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x18(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  sar    $0x4,%eax
  and    $0xc,%eax
  or     %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0x18(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  sar    $0x6,%al
  movsbl %al,%eax
  or     %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  xor    $0x2a,%eax
  mov    %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%edx
  mov    -0xc(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rcx
  lea    D42(%rip),%rax
  mov    (%rcx,%rax,1),%eax
  mov    %eax,%ecx
  sar    %cl,%edx
  mov    -0x28(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x8(%rbp),%rax
  pop    %rbp
  ret
```

tool_calls: name: disassemble_data
arguments: data_label: D24
type_guessed: string
name: disassemble_data
arguments: data_label: D12
type_guessed: string
name: disassemble_data
arguments: data_label: D44
type_guessed: string
name: disassemble_data
arguments: data_label: D13
type_guessed: string
name: disassemble_data
arguments: data_label: D42
type_guessed: string

tool: D24: 

tool: 

tool: 

tool: 

tool: 

assistant: ```c
const char *utf8_decode(const char *s, uint32_t *c, int *e) {
  static const char lengths[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0};
  static const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
  static const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
  static const int shiftc[] = {0, 18, 12, 6, 0};
  static const int shifte[] = {0, 6, 4, 2, 0};
  int len = lengths[s[0] >> 3];
  const char *next = s + len + !len;
  *c = (uint32_t)(s[0] & masks[len]) << 18;
  *c |= (uint32_t)(s[1] & 0x3f) << 12;
  *c |= (uint32_t)(s[2] & 0x3f) << 6;
  *c |= (uint32_t)(s[3] & 0x3f) << 0;
  *c >>= shiftc[len];
  *e = (*c < mins[len]) << 6;
  *e |= ((*c >> 11) == 0x1b) << 7;
  *e |= (*c > 0x10FFFF) << 8;
  *e |= (s[1] & 0xc0) >> 2;
  *e |= (s[2] & 0xc0) >> 4;
  *e |= (s[3]) >> 6;
  *e ^= 0x2a;
  *e >>= shifte[len];
  return next;
}
```