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

```asm
<parse_protos>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x40,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    %rdx,-0x38(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %rax,-0x8(%rbp)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  je     L39
  mov    D28(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <ERR_print_errors_fp@plt>
  mov    $0x0,%edi
  call   <OPENSSL_assert@plt>
L39:
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,%rdi
  call   <OPENSSL_malloc@plt>
  mov    -0x30(%rbp),%rdx
  mov    %rax,(%rdx)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  jne    L47
  mov    D28(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <ERR_print_errors_fp@plt>
  mov    $0x0,%edi
  call   <OPENSSL_assert@plt>
L47:
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    -0x38(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rax
  lea    0x1(%rax),%rcx
  mov    -0x8(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    %rax,%rsi
  mov    %rcx,%rdi
  call   <memcpy@plt>
  movq   $0x0,-0x10(%rbp)
  mov    -0x10(%rbp),%rax
  add    $0x1,%rax
  mov    %rax,-0x18(%rbp)
  jmp    L63
L21:
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0x2c,%al
  jne    L37
  mov    -0x18(%rbp),%rax
  sub    -0x10(%rbp),%rax
  cmp    $0x1,%rax
  jne    L0
  mov    D28(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <ERR_print_errors_fp@plt>
  mov    $0x0,%edi
  call   <OPENSSL_assert@plt>
L0:
  mov    -0x18(%rbp),%rax
  mov    %eax,%edx
  mov    -0x10(%rbp),%rax
  sub    %eax,%edx
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rcx
  mov    -0x10(%rbp),%rax
  add    %rcx,%rax
  sub    $0x1,%edx
  mov    %dl,(%rax)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x10(%rbp)
L37:
  addq   $0x1,-0x18(%rbp)
L63:
  mov    -0x18(%rbp),%rax
  cmp    -0x8(%rbp),%rax
  jbe    L21
  mov    -0x8(%rbp),%rax
  cmp    -0x10(%rbp),%rax
  jne    L42
  mov    D28(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,%edi
  call   <ERR_print_errors_fp@plt>
  mov    $0x0,%edi
  call   <OPENSSL_assert@plt>
L42:
  mov    -0x8(%rbp),%rax
  mov    %eax,%ecx
  mov    -0x10(%rbp),%rax
  mov    %eax,%esi
  mov    -0x30(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x10(%rbp),%rax
  add    %rdx,%rax
  sub    %esi,%ecx
  mov    %ecx,%edx
  mov    %dl,(%rax)
  nop
  leave
  ret
```

assistant: ```c
void parse_protos(const char *protos, unsigned char **out, size_t *outlen) {
  size_t len, i, prefix;
  len = strlen(protos);
  do {
    if (!(*out == NULL)) {
      ERR_print_errors_fp(stderr);
      OPENSSL_assert(!"*out == NULL");
    }
  } while (0);
  ;
  *out = OPENSSL_malloc(len + 1);
  do {
    if (!(*out != NULL)) {
      ERR_print_errors_fp(stderr);
      OPENSSL_assert(!"*out != NULL");
    }
  } while (0);
  ;
  *outlen = len + 1;
  memcpy(*out + 1, protos, len);
  prefix = 0;
  i = prefix + 1;
  while (i <= len) {
    if ((*out)[i] == ',') {
      do {
        if (!(i - 1 - prefix > 0)) {
          ERR_print_errors_fp(stderr);
          OPENSSL_assert(!"i - 1 - prefix > 0");
        }
      } while (0);
      ;
      (*out)[prefix] = i - 1 - prefix;
      prefix = i;
    }
    i++;
  }
  do {
    if (!(len - prefix > 0)) {
      ERR_print_errors_fp(stderr);
      OPENSSL_assert(!"len - prefix > 0");
    }
  } while (0);
  ;
  (*out)[prefix] = len - prefix;
}
```