user: 提供的汇编代码用C语言表示会是什么样子:

```asm
<utf8_is_valid>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %esi,-0x2c(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    %rcx,-0x40(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x2c(%rbp),%eax
  cltq
  lea    0x0(,%rax,4),%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x40(%rbp),%rax
  movl   $0x0,(%rax)
  jmp    L67
L17:
  movl   $0x0,-0x14(%rbp)
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <utf8_check_1@plt>
  test   %rax,%rax
  je     L50
  addq   $0x4,-0x10(%rbp)
  jmp    L67
L50:
  addl   $0x1,-0x14(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x14(%rbp),%ecx
  mov    -0x10(%rbp),%rax
  mov    %ecx,%esi
  mov    %rax,%rdi
  call   <utf8_check_boundary@plt>
  test   %rax,%rax
  je     L161
  mov    $0x4,%eax
  sub    -0x14(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L149
L161:
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <utf8_check_2@plt>
  test   %rax,%rax
  je     L113
  mov    -0x14(%rbp),%eax
  cltq
  add    $0x1,%rax
  shl    $0x2,%rax
  add    %rax,-0x10(%rbp)
  jmp    L67
L113:
  addl   $0x1,-0x14(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x14(%rbp),%ecx
  mov    -0x10(%rbp),%rax
  mov    %ecx,%esi
  mov    %rax,%rdi
  call   <utf8_check_boundary@plt>
  test   %rax,%rax
  je     L137
  mov    $0x4,%eax
  sub    -0x14(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L149
L137:
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <utf8_check_3@plt>
  test   %rax,%rax
  je     L152
  mov    -0x14(%rbp),%eax
  cltq
  add    $0x1,%rax
  shl    $0x2,%rax
  add    %rax,-0x10(%rbp)
  jmp    L67
L152:
  addl   $0x1,-0x14(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x14(%rbp),%ecx
  mov    -0x10(%rbp),%rax
  mov    %ecx,%esi
  mov    %rax,%rdi
  call   <utf8_check_boundary@plt>
  test   %rax,%rax
  je     L167
  mov    $0x4,%eax
  sub    -0x14(%rbp),%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  jmp    L149
L167:
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <utf8_check_4@plt>
  test   %rax,%rax
  je     L40
  mov    -0x14(%rbp),%eax
  cltq
  add    $0x1,%rax
  shl    $0x2,%rax
  add    %rax,-0x10(%rbp)
  jmp    L67
L40:
  nop
L149:
  mov    -0x38(%rbp),%rax
  mov    -0x10(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    $0x0,%eax
  jmp    L108
L67:
  mov    -0x10(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jb     L17
  mov    -0x38(%rbp),%rax
  movq   $0x0,(%rax)
  mov    $0x1,%eax
L108:
  leave
  ret
```

assistant: ```c
bool utf8_is_valid(uint8_t *input, uint32_t length, uint8_t **bad, uint32_t *missing) {
  uint8_t *position;
  uint8_t *max;
  uint32_t n;
  position = input;
  max = input + length;
  *missing = 0;
  while (position < max) {
    n = 0;
    if (utf8_check_1(position)) {
      position++;
      continue;
    }
    n++;
    if (utf8_check_boundary(position, n, max)) {
      *missing = 4 - n;
      goto BOUNDARY;
    }
    if (utf8_check_2(position)) {
      position += n + 1;
      continue;
    }
    n++;
    if (utf8_check_boundary(position, n, max)) {
      *missing = 4 - n;
      goto BOUNDARY;
    }
    if (utf8_check_3(position)) {
      position += n + 1;
      continue;
    }
    n++;
    if (utf8_check_boundary(position, n, max)) {
      *missing = 4 - n;
      goto BOUNDARY;
    }
    if (utf8_check_4(position)) {
      position += n + 1;
      continue;
    }
  BOUNDARY:
    *bad = position;
    return (false);
  }
  *bad = NULL;
  return (true);
}
```