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

```asm
<_fixpath>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x30(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x3a,%al
  jne    L99
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x60,%al
  jle    L146
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x7a,%al
  jle    L56
L146:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x40,%al
  jle    L99
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5a,%al
  jg     L99
L56:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x60,%al
  jle    L132
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x7a,%al
  jg     L132
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  sub    $0x61,%eax
  mov    %eax,-0x14(%rbp)
  jmp    L78
L132:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  sub    $0x41,%eax
  mov    %eax,-0x14(%rbp)
L78:
  mov    -0x10(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x8(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  mov    -0x10(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x8(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  jmp    L15
L99:
  mov    $0x0,%eax
  call   <_get_default_drive@plt>
  mov    %eax,-0x14(%rbp)
  mov    -0x14(%rbp),%eax
  lea    0x61(%rax),%ecx
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  mov    %ecx,%edx
  mov    %dl,(%rax)
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movb   $0x3a,(%rax)
L15:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <is_slash@plt>
  test   %rax,%rax
  jne    L63
  mov    -0x14(%rbp),%edx
  mov    -0x8(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <get_current_directory@plt>
  mov    %rax,-0x8(%rbp)
  jmp    L63
L29:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <is_slash@plt>
  test   %rax,%rax
  je     L191
  addq   $0x1,-0x10(%rbp)
  jmp    L63
L191:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L97
  mov    -0x10(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <is_term@plt>
  test   %rax,%rax
  je     L97
  addq   $0x1,-0x10(%rbp)
  jmp    L63
L97:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L179
  mov    -0x10(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  cmp    $0x2e,%al
  jne    L179
  mov    -0x10(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <is_term@plt>
  test   %rax,%rax
  je     L179
  addq   $0x2,-0x10(%rbp)
  mov    -0x30(%rbp),%rax
  add    $0x2,%rax
  cmp    %rax,-0x8(%rbp)
  jbe    L63
  nop
L207:
  subq   $0x1,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <is_slash@plt>
  test   %rax,%rax
  je     L207
  jmp    L63
L179:
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movb   $0x2f,(%rax)
  jmp    L82
L142:
  mov    -0x10(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x8(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
L82:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <is_term@plt>
  test   %rax,%rax
  je     L142
L63:
  mov    -0x10(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L29
  mov    -0x30(%rbp),%rax
  add    $0x2,%rax
  cmp    %rax,-0x8(%rbp)
  jne    L70
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movb   $0x2f,(%rax)
L70:
  mov    -0x8(%rbp),%rax
  movb   $0x0,(%rax)
  nop
  leave
  ret
```

assistant: ```c
void _fixpath(const char *in, char *out) {
  int drive_number;
  const char *ip = in;
  char *op = out;
  if (*(ip + 1) == ':' && ((*ip >= 'a' && *ip <= 'z') || (*ip >= 'A' && *ip <= 'Z'))) {
    if (*ip >= 'a' && *ip <= 'z')
      drive_number = *ip - 'a';
    else
      drive_number = *ip - 'A';
    *op++ = *ip++;
    *op++ = *ip++;
  } else {
    drive_number = _get_default_drive();
    *op++ = drive_number + 'a';
    *op++ = ':';
  }
  if (!is_slash(*ip))
    op = get_current_directory(op, drive_number);
  while (*ip) {
    if (is_slash(*ip)) {
      ip++;
      continue;
    }
    if (*ip == '.' && is_term(*(ip + 1))) {
      ip++;
      continue;
    }
    if (*ip == '.' && *(ip + 1) == '.' && is_term(*(ip + 2))) {
      ip += 2;
      if (op > out + 2)
        while (!is_slash(*--op))
          ;
      continue;
    }
    *op++ = '/';
    while (!is_term(*ip))
      *op++ = *ip++;
  }
  if (op == out + 2)
    *op++ = '/';
  *op = '\0';
}
```