user: Converte this assembly snippet into its equivalent C code:

```asm
<json_string_dump>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movq   $0x0,-0x18(%rbp)
  jmp    L128
L102:
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x1f,%al
  jbe    L31
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x7e,%al
  ja     L31
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x22,%al
  je     L126
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  jne    L23
L126:
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x5c,(%rax)
L23:
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rcx),%edx
  mov    %dl,(%rax)
  jmp    L18
L31:
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x9,%al
  jne    L44
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x5c,(%rax)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x74,(%rax)
  jmp    L18
L44:
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xa,%al
  jne    L47
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x5c,(%rax)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x6e,(%rax)
  jmp    L18
L47:
  mov    -0x30(%rbp),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x1f,%al
  ja     L94
  mov    -0x38(%rbp),%rax
  sub    -0x18(%rbp),%rax
  mov    %rax,%rdx
  mov    -0x30(%rbp),%rcx
  mov    -0x18(%rbp),%rax
  add    %rax,%rcx
  lea    -0x20(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <utf8_read@plt>
  add    %rax,-0x18(%rbp)
  mov    -0x20(%rbp),%eax
  mov    %eax,%edi
  call   <htons@plt>
  mov    %eax,-0x1c(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x5c,(%rax)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movb   $0x75,(%rax)
  lea    -0x1c(%rbp),%rcx
  mov    -0x28(%rbp),%rax
  mov    $0x4,%edx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <format_hex@plt>
  mov    %rax,-0x28(%rbp)
  nop
  jmp    L128
L94:
  mov    -0x38(%rbp),%rax
  sub    -0x18(%rbp),%rax
  mov    -0x30(%rbp),%rcx
  mov    -0x18(%rbp),%rdx
  add    %rdx,%rcx
  mov    %rax,%rdx
  mov    %rcx,%rsi
  mov    $0x0,%edi
  call   <utf8_read@plt>
  mov    %rax,-0x10(%rbp)
  jmp    L22
L15:
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  mov    -0x30(%rbp),%rdx
  lea    (%rax,%rdx,1),%rcx
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rcx),%edx
  mov    %dl,(%rax)
L22:
  mov    -0x10(%rbp),%rax
  lea    -0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  test   %rax,%rax
  jne    L15
  jmp    L128
L18:
  addq   $0x1,-0x18(%rbp)
L128:
  mov    -0x18(%rbp),%rax
  cmp    -0x38(%rbp),%rax
  jb     L102
  mov    -0x28(%rbp),%rax
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L78
  call   <__stack_chk_fail@plt>
L78:
  leave
  ret
```

assistant: ```c
char *json_string_dump(unsigned char *restrict dest, const unsigned char *restrict src, size_t size) {
  size_t i = 0;
  while (i < size) {
    if ((0x1f < src[i]) && (src[i] < 0x7f)) {
      if ((src[i] == '"') || (src[i] == '\\'))
        *dest++ = '\\';
      *dest++ = src[i];
    } else if (src[i] == '\t') {
      *dest++ = '\\';
      *dest++ = 't';
    } else if (src[i] == '\n') {
      *dest++ = '\\';
      *dest++ = 'n';
    } else if (src[i] <= 0x1f) {
      uint32_t code;
      uint16_t character;
      i += utf8_read(&code, src + i, size - i);
      character = htons(code);
      *dest++ = '\\';
      *dest++ = 'u';
      dest = format_hex(dest, (char *)&character, sizeof(character));
      continue;
    } else {
      size_t bytes = utf8_read(0, src + i, size - i);
      while (bytes--)
        *dest++ = src[i++];
      continue;
    }
    ++i;
  }
  return dest;
}
```