user: Please show me the C implementation that matches the assembly code listed below:

```asm
<pet_filename_to_host>:
  endbr64
  push   %r15
  mov    %rsi,%rax
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  sub    $0x18,%rsp
  mov    %rdx,(%rsp)
  mov    (%rsi),%edx
  and    $0x7f,%dl
  cmp    $0x20,%edx
  jne    L529
  mov    0x4(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L504
  mov    0x8(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L286
  mov    0xc(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L386
  mov    0x10(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L133
  mov    0x14(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L47
  mov    0x18(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L13
  mov    0x1c(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L112
  mov    0x20(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L499
  mov    0x24(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L472
  mov    0x28(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L542
  mov    0x2c(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L695
  mov    0x30(%rsi),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L256
  mov    0x34(%rsi),%ecx
  mov    %ecx,%esi
  and    $0x7f,%sil
  cmp    $0x20,%esi
  jne    L393
  mov    0x38(%rax),%esi
  mov    %esi,%edi
  and    $0x7f,%dil
  cmp    $0x20,%edi
  jne    L699
  mov    0x3c(%rax),%esi
  mov    $0x10,%r14d
  and    $0x7f,%sil
  cmp    $0x20,%esi
  jne    L32
L198:
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L278
  mov    0x30(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L550
  mov    0x2c(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L449
  mov    0x28(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L114
  mov    0x24(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L327
  mov    0x20(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L158
  mov    0x1c(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L135
  mov    0x18(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L565
  mov    0x14(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L263
  mov    0x10(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L608
  mov    0xc(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L571
  mov    0x8(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L483
  mov    0x4(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L254
  xor    %r12d,%r12d
  cmp    $0x20,%edx
  jne    L526
  xor    %r14d,%r14d
L118:
  movb   $0x0,(%rbx)
  mov    %rbx,%rax
  xor    %r15d,%r15d
  mov    %r14d,0x8(%rsp)
L287:
  mov    (%rsp),%rsi
  test   %rsi,%rsi
  je     L283
  cmpb   $0x0,(%rsi)
  jne    L648
L283:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L278:
  mov    $0xd,%r12d
  nopl   0x0(%rax,%rax,1)
L526:
  lea    0x1(%r12),%edi
  mov    %edi,0x8(%rsp)
  cmp    %r14d,%edi
  jle    L300
L488:
  mov    0x8(%rsp),%esi
  sub    %r14d,%esi
  mov    %esi,0xc(%rsp)
  test   %esi,%esi
  jle    L567
L219:
  mov    0xc(%rsp),%edx
  movslq %r14d,%rdi
  mov    %rbx,%r15
  lea    (%rax,%rdi,4),%r12
  sub    $0x1,%edx
  add    %rdi,%rdx
  lea    0x4(%rax,%rdx,4),%r13
  jmp    L537
  nopl   0x0(%rax)
L127:
  mov    $0x5f,%edx
  add    $0x4,%r12
  add    $0x1,%r15
  mov    %dl,-0x1(%r15)
  cmp    %r13,%r12
  je     L567
L537:
  mov    (%r12),%edi
  call   <pet_to_asc@plt>
  mov    %eax,%edi
  mov    %eax,%ebp
  call   <isprint@plt>
  test   %rax,%rax
  je     L127
  mov    %ebp,%edi
  call   <is_host_allowed_char@plt>
  test   %rax,%rax
  je     L127
  mov    %ebp,%edx
  add    $0x4,%r12
  add    $0x1,%r15
  mov    %dl,-0x1(%r15)
  cmp    %r13,%r12
  jne    L537
  nopl   0x0(%rax)
L567:
  movslq 0xc(%rsp),%r15
  lea    (%rbx,%r15,1),%rax
  movb   $0x0,(%rax)
  jmp    L287
  nopl   0x0(%rax)
L648:
  mov    0x8(%rsp),%edi
  movb   $0x2e,(%rax)
  mov    $0x3,%edx
  add    $0x1,%edi
  movslq %edi,%rdi
  sub    %r14,%rdi
  add    %rbx,%rdi
  call   <memcpy@plt>
  movb   $0x0,0x4(%rbx,%r15,1)
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L529:
  xor    %r14d,%r14d
  nopl   (%rax)
L82:
  mov    0x3c(%rax),%ecx
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  jne    L316
  mov    0x38(%rax),%esi
L635:
  and    $0x7f,%sil
  cmp    $0x20,%esi
  jne    L619
  mov    0x34(%rax),%ecx
  jmp    L198
L504:
  mov    $0x1,%r14d
  jmp    L82
L619:
  movl   $0xf,0x8(%rsp)
  jmp    L488
L256:
  mov    $0xc,%r14d
  jmp    L82
L286:
  mov    $0x2,%r14d
  jmp    L82
L550:
  mov    $0xc,%r12d
  jmp    L526
L386:
  mov    $0x3,%r14d
  jmp    L82
L133:
  mov    $0x4,%r14d
  jmp    L82
L449:
  mov    $0xb,%r12d
  jmp    L526
L114:
  mov    $0xa,%r12d
  jmp    L526
L47:
  mov    $0x5,%r14d
  jmp    L82
L13:
  mov    $0x6,%r14d
  jmp    L82
L327:
  mov    $0x9,%r12d
  jmp    L526
L158:
  mov    $0x8,%r12d
  jmp    L526
L112:
  mov    $0x7,%r14d
  jmp    L82
L499:
  mov    $0x8,%r14d
  jmp    L82
L135:
  mov    $0x7,%r12d
  jmp    L526
L565:
  mov    $0x6,%r12d
  jmp    L526
L472:
  mov    $0x9,%r14d
  jmp    L82
L542:
  mov    $0xa,%r14d
  jmp    L82
L263:
  mov    $0x5,%r12d
  jmp    L526
L316:
  mov    $0x10,%r15d
  movl   $0x10,0x8(%rsp)
  sub    %r14d,%r15d
  mov    %r15d,0xc(%rsp)
  jmp    L219
L608:
  mov    $0x4,%r12d
  jmp    L526
L695:
  mov    $0xb,%r14d
  jmp    L82
L571:
  mov    $0x3,%r12d
  jmp    L526
L483:
  mov    $0x2,%r12d
  jmp    L526
L393:
  mov    $0xd,%r14d
  jmp    L82
L254:
  mov    $0x1,%r12d
  jmp    L526
L699:
  mov    0x3c(%rax),%ecx
  mov    $0xe,%r14d
  and    $0x7f,%cl
  cmp    $0x20,%ecx
  je     L635
L451:
  movl   $0x10,0x8(%rsp)
  jmp    L488
L32:
  mov    $0xf,%r14d
  jmp    L451
L300:
  movslq 0x8(%rsp),%r14
  jmp    L118
```

assistant: ```c
void pet_filename_to_host(char *asc, const uint8_t *pet, const char *ext) {
  int lead = 0;
  int trail = 16 - 1;
  while (lead < 16 && (pet[lead] == 0x20 || pet[lead] == 0xa0)) {
    lead++;
  }
  while (trail >= 0 && (pet[trail] == 0x20 || pet[trail] == 0xa0)) {
    trail--;
  }
  trail++;
  if (lead < trail) {
    int i;
    for (i = 0; i < trail - lead; i++) {
      int b = pet_to_asc(pet[lead + i]);
      asc[i] = isprint(b) && is_host_allowed_char(b) ? (char)b : '_';
    }
    asc[trail - lead] = '\0';
  } else {
    lead = trail;
    asc[0] = '\0';
  }
  if (ext != NULL && *ext != '\0') {
    asc[trail - lead] = '.';
    memcpy(asc + trail - lead + 1, ext, 3);
    asc[trail - lead + 4] = '\0';
  }
}
```